Du kannst nicht mehr als 25 Themen auswählen Themen müssen mit entweder einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

server.go 66KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215
  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. "fmt"
  11. "log"
  12. "math/rand"
  13. "net"
  14. "os"
  15. "os/signal"
  16. "strconv"
  17. "strings"
  18. "sync"
  19. "syscall"
  20. "time"
  21. "github.com/goshuirc/irc-go/ircfmt"
  22. "github.com/goshuirc/irc-go/ircmsg"
  23. "github.com/oragono/oragono/irc/caps"
  24. "github.com/oragono/oragono/irc/isupport"
  25. "github.com/oragono/oragono/irc/logger"
  26. "github.com/oragono/oragono/irc/passwd"
  27. "github.com/oragono/oragono/irc/sno"
  28. "github.com/oragono/oragono/irc/utils"
  29. "github.com/tidwall/buntdb"
  30. )
  31. var (
  32. // common error line to sub values into
  33. errorMsg, _ = (&[]ircmsg.IrcMessage{ircmsg.MakeMessage(nil, "", "ERROR", "%s ")}[0]).Line()
  34. // common error responses
  35. couldNotParseIPMsg, _ = (&[]ircmsg.IrcMessage{ircmsg.MakeMessage(nil, "", "ERROR", "Unable to parse your IP address")}[0]).Line()
  36. )
  37. const (
  38. 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."
  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
  65. }
  66. // Server is the main Oragono server.
  67. type Server struct {
  68. accountAuthenticationEnabled bool
  69. accountRegistration *AccountRegistration
  70. accounts map[string]*ClientAccount
  71. channelRegistrationEnabled bool
  72. channels ChannelNameMap
  73. channelJoinPartMutex sync.Mutex // used when joining/parting channels to prevent stomping over each others' access and all
  74. checkIdent bool
  75. clients *ClientLookupSet
  76. commands chan Command
  77. configFilename string
  78. configurableStateMutex sync.RWMutex // generic protection for server state modified by rehash()
  79. connectionLimits *ConnectionLimits
  80. connectionLimitsMutex sync.Mutex // used when affecting the connection limiter, to make sure rehashing doesn't make things go out-of-whack
  81. connectionThrottle *ConnectionThrottle
  82. connectionThrottleMutex sync.Mutex // used when affecting the connection limiter, to make sure rehashing doesn't make things go out-of-whack
  83. ctime time.Time
  84. defaultChannelModes Modes
  85. dlines *DLineManager
  86. loggingRawIO bool
  87. isupport *isupport.List
  88. klines *KLineManager
  89. limits Limits
  90. listeners map[string]*ListenerWrapper
  91. logger *logger.Manager
  92. MaxSendQBytes uint64
  93. monitorManager *MonitorManager
  94. motdLines []string
  95. name string
  96. nameCasefolded string
  97. networkName string
  98. newConns chan clientConn
  99. operators map[string]Oper
  100. operclasses map[string]OperClass
  101. password []byte
  102. passwords *passwd.SaltedManager
  103. registeredChannels map[string]*RegisteredChannel
  104. registeredChannelsMutex sync.RWMutex
  105. rehashMutex sync.Mutex
  106. rehashSignal chan os.Signal
  107. proxyAllowedFrom []string
  108. signals chan os.Signal
  109. snomasks *SnoManager
  110. store *buntdb.DB
  111. stsEnabled bool
  112. whoWas *WhoWasList
  113. }
  114. var (
  115. // ServerExitSignals are the signals the server will exit on.
  116. ServerExitSignals = []os.Signal{
  117. syscall.SIGINT,
  118. syscall.SIGTERM,
  119. syscall.SIGQUIT,
  120. }
  121. )
  122. type clientConn struct {
  123. Conn net.Conn
  124. IsTLS bool
  125. }
  126. // NewServer returns a new Oragono server.
  127. func NewServer(config *Config, logger *logger.Manager) (*Server, error) {
  128. // TODO move this to main?
  129. if err := GenerateHelpIndices(); err != nil {
  130. return nil, err
  131. }
  132. // initialize data structures
  133. server := &Server{
  134. accounts: make(map[string]*ClientAccount),
  135. channels: *NewChannelNameMap(),
  136. clients: NewClientLookupSet(),
  137. commands: make(chan Command),
  138. listeners: make(map[string]*ListenerWrapper),
  139. logger: logger,
  140. monitorManager: NewMonitorManager(),
  141. newConns: make(chan clientConn),
  142. registeredChannels: make(map[string]*RegisteredChannel),
  143. rehashSignal: make(chan os.Signal, 1),
  144. signals: make(chan os.Signal, len(ServerExitSignals)),
  145. snomasks: NewSnoManager(),
  146. whoWas: NewWhoWasList(config.Limits.WhowasEntries),
  147. }
  148. if err := server.applyConfig(config, true); err != nil {
  149. return nil, err
  150. }
  151. // Attempt to clean up when receiving these signals.
  152. signal.Notify(server.signals, ServerExitSignals...)
  153. signal.Notify(server.rehashSignal, syscall.SIGHUP)
  154. return server, nil
  155. }
  156. // setISupport sets up our RPL_ISUPPORT reply.
  157. func (server *Server) setISupport() {
  158. maxTargetsString := strconv.Itoa(maxTargets)
  159. server.configurableStateMutex.RLock()
  160. // add RPL_ISUPPORT tokens
  161. isupport := isupport.NewList()
  162. isupport.Add("AWAYLEN", strconv.Itoa(server.limits.AwayLen))
  163. isupport.Add("CASEMAPPING", casemappingName)
  164. isupport.Add("CHANMODES", strings.Join([]string{Modes{BanMask, ExceptMask, InviteMask}.String(), "", Modes{UserLimit, Key}.String(), Modes{InviteOnly, Moderated, NoOutside, OpOnlyTopic, ChanRoleplaying, Secret}.String()}, ","))
  165. isupport.Add("CHANNELLEN", strconv.Itoa(server.limits.ChannelLen))
  166. isupport.Add("CHANTYPES", "#")
  167. isupport.Add("ELIST", "U")
  168. isupport.Add("EXCEPTS", "")
  169. isupport.Add("INVEX", "")
  170. isupport.Add("KICKLEN", strconv.Itoa(server.limits.KickLen))
  171. isupport.Add("MAXLIST", fmt.Sprintf("beI:%s", strconv.Itoa(server.limits.ChanListModes)))
  172. isupport.Add("MAXTARGETS", maxTargetsString)
  173. isupport.Add("MODES", "")
  174. isupport.Add("MONITOR", strconv.Itoa(server.limits.MonitorEntries))
  175. isupport.Add("NETWORK", server.networkName)
  176. isupport.Add("NICKLEN", strconv.Itoa(server.limits.NickLen))
  177. isupport.Add("PREFIX", "(qaohv)~&@%+")
  178. isupport.Add("RPCHAN", "E")
  179. isupport.Add("RPUSER", "E")
  180. isupport.Add("STATUSMSG", "~&@%+")
  181. 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))
  182. isupport.Add("TOPICLEN", strconv.Itoa(server.limits.TopicLen))
  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. server.clients.ByNickMutex.RLock()
  212. for _, client := range server.clients.ByNick {
  213. client.Notice("Server is shutting down")
  214. }
  215. server.clients.ByNickMutex.RUnlock()
  216. if err := server.store.Close(); err != nil {
  217. server.logger.Error("shutdown", fmt.Sprintln("Could not close datastore:", err))
  218. }
  219. }
  220. // Run starts the server.
  221. func (server *Server) Run() {
  222. // defer closing db/store
  223. defer server.store.Close()
  224. done := false
  225. for !done {
  226. select {
  227. case <-server.signals:
  228. server.Shutdown()
  229. done = true
  230. case <-server.rehashSignal:
  231. server.logger.Info("rehash", "Rehashing due to SIGHUP")
  232. go func() {
  233. err := server.rehash()
  234. if err != nil {
  235. server.logger.Error("rehash", fmt.Sprintln("Failed to rehash:", err.Error()))
  236. }
  237. }()
  238. case conn := <-server.newConns:
  239. // check IP address
  240. ipaddr := net.ParseIP(utils.IPString(conn.Conn.RemoteAddr()))
  241. if ipaddr == nil {
  242. conn.Conn.Write([]byte(couldNotParseIPMsg))
  243. conn.Conn.Close()
  244. continue
  245. }
  246. isBanned, banMsg := server.checkBans(ipaddr)
  247. if isBanned {
  248. // this might not show up properly on some clients, but our objective here is just to close the connection out before it has a load impact on us
  249. conn.Conn.Write([]byte(fmt.Sprintf(errorMsg, banMsg)))
  250. conn.Conn.Close()
  251. continue
  252. }
  253. server.logger.Debug("localconnect-ip", fmt.Sprintf("Client connecting from %v", ipaddr))
  254. // prolly don't need to alert snomasks on this, only on connection reg
  255. go NewClient(server, conn.Conn, conn.IsTLS)
  256. continue
  257. }
  258. }
  259. }
  260. func (server *Server) checkBans(ipaddr net.IP) (banned bool, message string) {
  261. // check DLINEs
  262. isBanned, info := server.dlines.CheckIP(ipaddr)
  263. if isBanned {
  264. return true, info.BanMessage("You are banned from this server (%s)")
  265. }
  266. // check connection limits
  267. server.connectionLimitsMutex.Lock()
  268. err := server.connectionLimits.AddClient(ipaddr, false)
  269. server.connectionLimitsMutex.Unlock()
  270. if err != nil {
  271. // too many connections from one client, tell the client and close the connection
  272. return true, "Too many clients from your network"
  273. }
  274. // check connection throttle
  275. server.connectionThrottleMutex.Lock()
  276. err = server.connectionThrottle.AddClient(ipaddr)
  277. server.connectionThrottleMutex.Unlock()
  278. if err != nil {
  279. // too many connections too quickly from client, tell them and close the connection
  280. length := &IPRestrictTime{
  281. Duration: server.connectionThrottle.BanDuration,
  282. Expires: time.Now().Add(server.connectionThrottle.BanDuration),
  283. }
  284. server.dlines.AddIP(ipaddr, length, server.connectionThrottle.BanMessage, "Exceeded automated connection throttle")
  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.connectionThrottle.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. return true, server.connectionThrottle.BanMessage
  290. }
  291. return false, ""
  292. }
  293. //
  294. // IRC protocol listeners
  295. //
  296. // createListener starts the given listeners.
  297. func (server *Server) createListener(addr string, tlsConfig *tls.Config) *ListenerWrapper {
  298. // make listener
  299. listener, err := net.Listen("tcp", addr)
  300. if err != nil {
  301. log.Fatal(server, "listen error: ", err)
  302. }
  303. // throw our details to the server so we can be modified/killed later
  304. wrapper := ListenerWrapper{
  305. listener: listener,
  306. tlsConfig: tlsConfig,
  307. shouldStop: false,
  308. stopEvent: make(chan bool, 1),
  309. }
  310. var shouldStop bool
  311. // setup accept goroutine
  312. go func() {
  313. for {
  314. conn, err := listener.Accept()
  315. // synchronously access config data:
  316. // whether TLS is enabled and whether we should stop listening
  317. wrapper.configMutex.Lock()
  318. shouldStop = wrapper.shouldStop
  319. tlsConfig = wrapper.tlsConfig
  320. wrapper.configMutex.Unlock()
  321. if err == nil {
  322. if tlsConfig != nil {
  323. conn = tls.Server(conn, tlsConfig)
  324. }
  325. newConn := clientConn{
  326. Conn: conn,
  327. IsTLS: tlsConfig != nil,
  328. }
  329. // hand off the connection
  330. server.newConns <- newConn
  331. }
  332. if shouldStop {
  333. listener.Close()
  334. wrapper.stopEvent <- true
  335. return
  336. }
  337. }
  338. }()
  339. return &wrapper
  340. }
  341. // generateMessageID returns a network-unique message ID.
  342. func (server *Server) generateMessageID() string {
  343. return fmt.Sprintf("%s-%s", strconv.FormatInt(time.Now().UTC().UnixNano(), 10), strconv.FormatInt(rand.Int63(), 10))
  344. }
  345. //
  346. // server functionality
  347. //
  348. func (server *Server) tryRegister(c *Client) {
  349. if c.registered || !c.HasNick() || !c.HasUsername() ||
  350. (c.capState == CapNegotiating) {
  351. return
  352. }
  353. // check KLINEs
  354. isBanned, info := server.klines.CheckMasks(c.AllNickmasks()...)
  355. if isBanned {
  356. reason := info.Reason
  357. if info.Time != nil {
  358. reason += fmt.Sprintf(" [%s]", info.Time.Duration.String())
  359. }
  360. c.Send(nil, "", "ERROR", fmt.Sprintf("You are banned from this server (%s)", reason))
  361. c.quitMessageSent = true
  362. c.destroy()
  363. return
  364. }
  365. // continue registration
  366. server.logger.Debug("localconnect", fmt.Sprintf("Client registered [%s] [u:%s] [r:%s]", c.nick, c.username, c.realname))
  367. 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))
  368. c.Register()
  369. // send welcome text
  370. //NOTE(dan): we specifically use the NICK here instead of the nickmask
  371. // see http://modern.ircdocs.horse/#rplwelcome-001 for details on why we avoid using the nickmask
  372. c.Send(nil, server.name, RPL_WELCOME, c.nick, fmt.Sprintf("Welcome to the Internet Relay Network %s", c.nick))
  373. c.Send(nil, server.name, RPL_YOURHOST, c.nick, fmt.Sprintf("Your host is %s, running version %s", server.name, Ver))
  374. c.Send(nil, server.name, RPL_CREATED, c.nick, fmt.Sprintf("This server was created %s", server.ctime.Format(time.RFC1123)))
  375. //TODO(dan): Look at adding last optional [<channel modes with a parameter>] parameter
  376. c.Send(nil, server.name, RPL_MYINFO, c.nick, server.name, Ver, supportedUserModesString, supportedChannelModesString)
  377. c.RplISupport()
  378. server.MOTD(c)
  379. c.Send(nil, c.nickMaskString, RPL_UMODEIS, c.nick, c.ModeString())
  380. if server.logger.IsLoggingRawIO() {
  381. c.Notice(rawIONotice)
  382. }
  383. }
  384. // MOTD serves the Message of the Day.
  385. func (server *Server) MOTD(client *Client) {
  386. server.configurableStateMutex.RLock()
  387. motdLines := server.motdLines
  388. server.configurableStateMutex.RUnlock()
  389. if len(motdLines) < 1 {
  390. client.Send(nil, server.name, ERR_NOMOTD, client.nick, "MOTD File is missing")
  391. return
  392. }
  393. client.Send(nil, server.name, RPL_MOTDSTART, client.nick, fmt.Sprintf("- %s Message of the day - ", server.name))
  394. for _, line := range motdLines {
  395. client.Send(nil, server.name, RPL_MOTD, client.nick, line)
  396. }
  397. client.Send(nil, server.name, RPL_ENDOFMOTD, client.nick, "End of MOTD command")
  398. }
  399. //
  400. // registration commands
  401. //
  402. // PASS <password>
  403. func passHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
  404. if client.registered {
  405. client.Send(nil, server.name, ERR_ALREADYREGISTRED, client.nick, "You may not reregister")
  406. return false
  407. }
  408. // if no password exists, skip checking
  409. if len(server.password) == 0 {
  410. client.authorized = true
  411. return false
  412. }
  413. // check the provided password
  414. password := []byte(msg.Params[0])
  415. if passwd.ComparePassword(server.password, password) != nil {
  416. client.Send(nil, server.name, ERR_PASSWDMISMATCH, client.nick, "Password incorrect")
  417. client.Send(nil, server.name, "ERROR", "Password incorrect")
  418. return true
  419. }
  420. client.authorized = true
  421. return false
  422. }
  423. // USER <username> * 0 <realname>
  424. func userHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
  425. if client.registered {
  426. client.Send(nil, server.name, ERR_ALREADYREGISTRED, client.nick, "You may not reregister")
  427. return false
  428. }
  429. if !client.authorized {
  430. client.Quit("Bad password")
  431. return true
  432. }
  433. if client.username != "" && client.realname != "" {
  434. return false
  435. }
  436. // confirm that username is valid
  437. //
  438. _, err := CasefoldName(msg.Params[0])
  439. if err != nil {
  440. client.Send(nil, "", "ERROR", "Malformed username")
  441. return true
  442. }
  443. if !client.HasUsername() {
  444. client.username = "~" + msg.Params[0]
  445. // don't bother updating nickmask here, it's not valid anyway
  446. }
  447. if client.realname == "" {
  448. client.realname = msg.Params[3]
  449. }
  450. server.tryRegister(client)
  451. return false
  452. }
  453. // QUIT [<reason>]
  454. func quitHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
  455. reason := "Quit"
  456. if len(msg.Params) > 0 {
  457. reason += ": " + msg.Params[0]
  458. }
  459. client.Quit(reason)
  460. return true
  461. }
  462. //
  463. // normal commands
  464. //
  465. // PING <server1> [<server2>]
  466. func pingHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
  467. client.Send(nil, server.name, "PONG", msg.Params...)
  468. return false
  469. }
  470. // PONG <server> [ <server2> ]
  471. func pongHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
  472. // client gets touched when they send this command, so we don't need to do anything
  473. return false
  474. }
  475. // RENAME <oldchan> <newchan> [<reason>]
  476. //TODO(dan): Clean up this function so it doesn't look like an eldrich horror... prolly by putting it into a server.renameChannel function.
  477. func renameHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
  478. // get lots of locks... make sure nobody touches anything while we're doing this
  479. server.registeredChannelsMutex.Lock()
  480. defer server.registeredChannelsMutex.Unlock()
  481. server.channels.ChansLock.Lock()
  482. defer server.channels.ChansLock.Unlock()
  483. oldName := strings.TrimSpace(msg.Params[0])
  484. newName := strings.TrimSpace(msg.Params[1])
  485. reason := "No reason"
  486. if 2 < len(msg.Params) {
  487. reason = msg.Params[2]
  488. }
  489. // check for all the reasons why the rename couldn't happen
  490. casefoldedOldName, err := CasefoldChannel(oldName)
  491. if err != nil {
  492. //TODO(dan): Change this to ERR_CANNOTRENAME
  493. client.Send(nil, server.name, ERR_UNKNOWNERROR, client.nick, "RENAME", oldName, "Old channel name is invalid")
  494. return false
  495. }
  496. channel := server.channels.Chans[casefoldedOldName]
  497. if channel == nil {
  498. client.Send(nil, server.name, ERR_NOSUCHCHANNEL, client.nick, oldName, "No such channel")
  499. return false
  500. }
  501. //TODO(dan): allow IRCops to do this?
  502. if !channel.ClientIsAtLeast(client, Operator) {
  503. client.Send(nil, server.name, ERR_CHANOPRIVSNEEDED, client.nick, oldName, "Only chanops can rename channels")
  504. return false
  505. }
  506. channel.membersMutex.Lock()
  507. defer channel.membersMutex.Unlock()
  508. casefoldedNewName, err := CasefoldChannel(newName)
  509. if err != nil {
  510. //TODO(dan): Change this to ERR_CANNOTRENAME
  511. client.Send(nil, server.name, ERR_UNKNOWNERROR, client.nick, "RENAME", newName, "New channel name is invalid")
  512. return false
  513. }
  514. newChannel := server.channels.Chans[casefoldedNewName]
  515. if newChannel != nil {
  516. //TODO(dan): Change this to ERR_CHANNAMEINUSE
  517. client.Send(nil, server.name, ERR_UNKNOWNERROR, client.nick, "RENAME", newName, "New channel name is in use")
  518. return false
  519. }
  520. var canEdit bool
  521. server.store.Update(func(tx *buntdb.Tx) error {
  522. chanReg := server.loadChannelNoMutex(tx, casefoldedOldName)
  523. if chanReg == nil || !client.LoggedIntoAccount() || client.account.Name == chanReg.Founder {
  524. canEdit = true
  525. }
  526. chanReg = server.loadChannelNoMutex(tx, casefoldedNewName)
  527. if chanReg != nil {
  528. canEdit = false
  529. }
  530. return nil
  531. })
  532. if !canEdit {
  533. //TODO(dan): Change this to ERR_CANNOTRENAME
  534. client.Send(nil, server.name, ERR_UNKNOWNERROR, client.nick, "RENAME", oldName, "Only channel founders can change registered channels")
  535. return false
  536. }
  537. // perform the channel rename
  538. server.channels.Chans[casefoldedOldName] = nil
  539. server.channels.Chans[casefoldedNewName] = channel
  540. channel.name = strings.TrimSpace(msg.Params[1])
  541. channel.nameCasefolded = casefoldedNewName
  542. // rename stored channel info if any exists
  543. server.store.Update(func(tx *buntdb.Tx) error {
  544. chanReg := server.loadChannelNoMutex(tx, casefoldedOldName)
  545. if chanReg == nil {
  546. return nil
  547. }
  548. server.deleteChannelNoMutex(tx, casefoldedOldName)
  549. chanReg.Name = newName
  550. server.saveChannelNoMutex(tx, casefoldedNewName, *chanReg)
  551. return nil
  552. })
  553. // send RENAME messages
  554. for mcl := range channel.members {
  555. if mcl.capabilities.Has(caps.Rename) {
  556. mcl.Send(nil, client.nickMaskString, "RENAME", oldName, newName, reason)
  557. } else {
  558. mcl.Send(nil, mcl.nickMaskString, "PART", oldName, fmt.Sprintf("Channel renamed: %s", reason))
  559. if mcl.capabilities.Has(caps.ExtendedJoin) {
  560. accountName := "*"
  561. if mcl.account != nil {
  562. accountName = mcl.account.Name
  563. }
  564. mcl.Send(nil, mcl.nickMaskString, "JOIN", newName, accountName, mcl.realname)
  565. } else {
  566. mcl.Send(nil, mcl.nickMaskString, "JOIN", newName)
  567. }
  568. }
  569. }
  570. return false
  571. }
  572. // JOIN <channel>{,<channel>} [<key>{,<key>}]
  573. func joinHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
  574. // kill JOIN 0 requests
  575. if msg.Params[0] == "0" {
  576. client.Notice("JOIN 0 is not allowed")
  577. return false
  578. }
  579. // handle regular JOINs
  580. channels := strings.Split(msg.Params[0], ",")
  581. var keys []string
  582. if len(msg.Params) > 1 {
  583. keys = strings.Split(msg.Params[1], ",")
  584. }
  585. // get lock
  586. server.channelJoinPartMutex.Lock()
  587. defer server.channelJoinPartMutex.Unlock()
  588. for i, name := range channels {
  589. casefoldedName, err := CasefoldChannel(name)
  590. if err != nil {
  591. if len(name) > 0 {
  592. client.Send(nil, server.name, ERR_NOSUCHCHANNEL, client.nick, name, "No such channel")
  593. }
  594. continue
  595. }
  596. channel := server.channels.Get(casefoldedName)
  597. if channel == nil {
  598. if len(casefoldedName) > server.getLimits().ChannelLen {
  599. client.Send(nil, server.name, ERR_NOSUCHCHANNEL, client.nick, name, "No such channel")
  600. continue
  601. }
  602. channel = NewChannel(server, name, true)
  603. }
  604. var key string
  605. if len(keys) > i {
  606. key = keys[i]
  607. }
  608. channel.Join(client, key)
  609. }
  610. return false
  611. }
  612. // PART <channel>{,<channel>} [<reason>]
  613. func partHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
  614. channels := strings.Split(msg.Params[0], ",")
  615. 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
  616. if len(msg.Params) > 1 {
  617. reason = msg.Params[1]
  618. }
  619. // get lock
  620. server.channelJoinPartMutex.Lock()
  621. defer server.channelJoinPartMutex.Unlock()
  622. for _, chname := range channels {
  623. casefoldedChannelName, err := CasefoldChannel(chname)
  624. channel := server.channels.Get(casefoldedChannelName)
  625. if err != nil || channel == nil {
  626. if len(chname) > 0 {
  627. client.Send(nil, server.name, ERR_NOSUCHCHANNEL, client.nick, chname, "No such channel")
  628. }
  629. continue
  630. }
  631. channel.Part(client, reason)
  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], "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.GetTopic(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, "No such channel")
  730. continue
  731. }
  732. if !channel.CanSpeak(client) {
  733. client.Send(nil, client.server.name, ERR_CANNOTSENDTOCHAN, channel.name, "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, "No such channel")
  798. continue
  799. }
  800. if !channel.CanSpeak(client) {
  801. client.Send(nil, client.server.name, ERR_CANNOTSENDTOCHAN, channel.name, "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, "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. index := 0
  837. for channel := range client.channels {
  838. channel.membersMutex.RLock()
  839. defer channel.membersMutex.RUnlock()
  840. // channel is secret and the target can't see it
  841. if !target.flags[Operator] && channel.flags[Secret] && !channel.members.Has(target) {
  842. continue
  843. }
  844. chstrs = append(chstrs, channel.members[client].Prefixes(isMultiPrefix)+channel.name)
  845. index++
  846. }
  847. return chstrs
  848. }
  849. // WHOIS [ <target> ] <mask> *( "," <mask> )
  850. func whoisHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
  851. var masksString string
  852. //var target string
  853. if len(msg.Params) > 1 {
  854. //target = msg.Params[0]
  855. masksString = msg.Params[1]
  856. } else {
  857. masksString = msg.Params[0]
  858. }
  859. if len(strings.TrimSpace(masksString)) < 1 {
  860. client.Send(nil, server.name, ERR_UNKNOWNERROR, client.nick, msg.Command, "No masks given")
  861. return false
  862. }
  863. if client.flags[Operator] {
  864. masks := strings.Split(masksString, ",")
  865. for _, mask := range masks {
  866. casefoldedMask, err := Casefold(mask)
  867. if err != nil {
  868. client.Send(nil, client.server.name, ERR_NOSUCHNICK, client.nick, mask, "No such nick")
  869. continue
  870. }
  871. matches := server.clients.FindAll(casefoldedMask)
  872. if len(matches) == 0 {
  873. client.Send(nil, client.server.name, ERR_NOSUCHNICK, client.nick, mask, "No such nick")
  874. continue
  875. }
  876. for mclient := range matches {
  877. client.getWhoisOf(mclient)
  878. }
  879. }
  880. } else {
  881. // only get the first request
  882. casefoldedMask, err := Casefold(strings.Split(masksString, ",")[0])
  883. mclient := server.clients.Get(casefoldedMask)
  884. if err != nil || mclient == nil {
  885. client.Send(nil, client.server.name, ERR_NOSUCHNICK, client.nick, masksString, "No such nick")
  886. // fall through, ENDOFWHOIS is always sent
  887. } else {
  888. client.getWhoisOf(mclient)
  889. }
  890. }
  891. client.Send(nil, server.name, RPL_ENDOFWHOIS, client.nick, masksString, "End of /WHOIS list")
  892. return false
  893. }
  894. func (client *Client) getWhoisOf(target *Client) {
  895. client.Send(nil, client.server.name, RPL_WHOISUSER, client.nick, target.nick, target.username, target.hostname, "*", target.realname)
  896. whoischannels := client.WhoisChannelsNames(target)
  897. if whoischannels != nil {
  898. client.Send(nil, client.server.name, RPL_WHOISCHANNELS, client.nick, target.nick, strings.Join(whoischannels, " "))
  899. }
  900. if target.class != nil {
  901. client.Send(nil, client.server.name, RPL_WHOISOPERATOR, client.nick, target.nick, target.whoisLine)
  902. }
  903. if client.flags[Operator] || client == target {
  904. 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")
  905. }
  906. if target.flags[TLS] {
  907. client.Send(nil, client.server.name, RPL_WHOISSECURE, client.nick, target.nick, "is using a secure connection")
  908. }
  909. if target.certfp != "" && (client.flags[Operator] || client == target) {
  910. client.Send(nil, client.server.name, RPL_WHOISCERTFP, client.nick, target.nick, fmt.Sprintf("has client certificate fingerprint %s", target.certfp))
  911. }
  912. 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")
  913. }
  914. // RplWhoReplyNoMutex returns the WHO reply between one user and another channel/user.
  915. // <channel> <user> <host> <server> <nick> ( "H" / "G" ) ["*"] [ ( "@" / "+" ) ]
  916. // :<hopcount> <real name>
  917. func (target *Client) RplWhoReplyNoMutex(channel *Channel, client *Client) {
  918. channelName := "*"
  919. flags := ""
  920. if client.flags[Away] {
  921. flags = "G"
  922. } else {
  923. flags = "H"
  924. }
  925. if client.flags[Operator] {
  926. flags += "*"
  927. }
  928. if channel != nil {
  929. flags += channel.members[client].Prefixes(target.capabilities.Has(caps.MultiPrefix))
  930. channelName = channel.name
  931. }
  932. 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)
  933. }
  934. func whoChannel(client *Client, channel *Channel, friends ClientSet) {
  935. channel.membersMutex.RLock()
  936. defer channel.membersMutex.RUnlock()
  937. for member := range channel.members {
  938. if !client.flags[Invisible] || friends[client] {
  939. client.RplWhoReplyNoMutex(channel, member)
  940. }
  941. }
  942. }
  943. // WHO [ <mask> [ "o" ] ]
  944. func whoHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
  945. friends := client.Friends()
  946. var mask string
  947. if len(msg.Params) > 0 {
  948. casefoldedMask, err := Casefold(msg.Params[0])
  949. if err != nil {
  950. client.Send(nil, server.name, ERR_UNKNOWNERROR, "WHO", "Mask isn't valid")
  951. return false
  952. }
  953. mask = casefoldedMask
  954. }
  955. //TODO(dan): is this used and would I put this param in the Modern doc?
  956. // if not, can we remove it?
  957. //var operatorOnly bool
  958. //if len(msg.Params) > 1 && msg.Params[1] == "o" {
  959. // operatorOnly = true
  960. //}
  961. if mask == "" {
  962. server.channels.ChansLock.RLock()
  963. for _, channel := range server.channels.Chans {
  964. whoChannel(client, channel, friends)
  965. }
  966. server.channels.ChansLock.RUnlock()
  967. } else if mask[0] == '#' {
  968. // TODO implement wildcard matching
  969. //TODO(dan): ^ only for opers
  970. channel := server.channels.Get(mask)
  971. if channel != nil {
  972. whoChannel(client, channel, friends)
  973. }
  974. } else {
  975. for mclient := range server.clients.FindAll(mask) {
  976. client.RplWhoReplyNoMutex(nil, mclient)
  977. }
  978. }
  979. client.Send(nil, server.name, RPL_ENDOFWHO, client.nick, mask, "End of WHO list")
  980. return false
  981. }
  982. // OPER <name> <password>
  983. func operHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
  984. name, err := CasefoldName(msg.Params[0])
  985. if err != nil {
  986. client.Send(nil, server.name, ERR_PASSWDMISMATCH, client.nick, "Password incorrect")
  987. return true
  988. }
  989. if client.flags[Operator] == true {
  990. client.Send(nil, server.name, ERR_UNKNOWNERROR, "OPER", "You're already opered-up!")
  991. return false
  992. }
  993. server.configurableStateMutex.RLock()
  994. oper := server.operators[name]
  995. server.configurableStateMutex.RUnlock()
  996. password := []byte(msg.Params[1])
  997. err = passwd.ComparePassword(oper.Pass, password)
  998. if (oper.Pass == nil) || (err != nil) {
  999. client.Send(nil, server.name, ERR_PASSWDMISMATCH, client.nick, "Password incorrect")
  1000. return true
  1001. }
  1002. client.flags[Operator] = true
  1003. client.operName = name
  1004. client.class = oper.Class
  1005. client.whoisLine = oper.WhoisLine
  1006. // push new vhost if one is set
  1007. if len(oper.Vhost) > 0 {
  1008. for fClient := range client.Friends(caps.ChgHost) {
  1009. fClient.SendFromClient("", client, nil, "CHGHOST", client.username, oper.Vhost)
  1010. }
  1011. // CHGHOST requires prefix nickmask to have original hostname, so do that before updating nickmask
  1012. client.vhost = oper.Vhost
  1013. client.updateNickMask("")
  1014. }
  1015. // set new modes
  1016. var applied ModeChanges
  1017. if 0 < len(oper.Modes) {
  1018. modeChanges, unknownChanges := ParseUserModeChanges(strings.Split(oper.Modes, " ")...)
  1019. applied = client.applyUserModeChanges(true, modeChanges)
  1020. if 0 < len(unknownChanges) {
  1021. var runes string
  1022. for r := range unknownChanges {
  1023. runes += string(r)
  1024. }
  1025. client.Notice(fmt.Sprintf("Could not apply mode changes: +%s", runes))
  1026. }
  1027. }
  1028. client.Send(nil, server.name, RPL_YOUREOPER, client.nick, "You are now an IRC operator")
  1029. applied = append(applied, ModeChange{
  1030. mode: Operator,
  1031. op: Add,
  1032. })
  1033. client.Send(nil, server.name, "MODE", client.nick, applied.String())
  1034. 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))
  1035. return false
  1036. }
  1037. // rehash reloads the config and applies the changes from the config file.
  1038. func (server *Server) rehash() error {
  1039. server.logger.Debug("rehash", "Starting rehash")
  1040. // only let one REHASH go on at a time
  1041. server.rehashMutex.Lock()
  1042. defer server.rehashMutex.Unlock()
  1043. server.logger.Debug("rehash", "Got rehash lock")
  1044. config, err := LoadConfig(server.configFilename)
  1045. if err != nil {
  1046. return fmt.Errorf("Error loading config file config: %s", err.Error())
  1047. }
  1048. err = server.applyConfig(config, false)
  1049. if err != nil {
  1050. return fmt.Errorf("Error applying config changes: %s", err.Error())
  1051. }
  1052. return nil
  1053. }
  1054. func (server *Server) applyConfig(config *Config, initial bool) error {
  1055. if initial {
  1056. server.ctime = time.Now()
  1057. server.configFilename = config.Filename
  1058. } else {
  1059. // enforce configs that can't be changed after launch:
  1060. if server.limits.LineLen.Tags != config.Limits.LineLen.Tags || server.limits.LineLen.Rest != config.Limits.LineLen.Rest {
  1061. return fmt.Errorf("Maximum line length (linelen) cannot be changed after launching the server, rehash aborted")
  1062. } else if server.name != config.Server.Name {
  1063. return fmt.Errorf("Server name cannot be changed after launching the server, rehash aborted")
  1064. }
  1065. }
  1066. casefoldedName, err := Casefold(config.Server.Name)
  1067. if err != nil {
  1068. return fmt.Errorf("Server name isn't valid [%s]: %s", config.Server.Name, err.Error())
  1069. }
  1070. // confirm connectionLimits are fine
  1071. connectionLimits, err := NewConnectionLimits(config.Server.ConnectionLimits)
  1072. if err != nil {
  1073. return fmt.Errorf("Error rehashing config file connection-limits: %s", err.Error())
  1074. }
  1075. // confirm connectionThrottler is fine
  1076. connectionThrottle, err := NewConnectionThrottle(config.Server.ConnectionThrottle)
  1077. if err != nil {
  1078. return fmt.Errorf("Error rehashing config file connection-throttle: %s", err.Error())
  1079. }
  1080. // confirm operator stuff all exists and is fine
  1081. operclasses, err := config.OperatorClasses()
  1082. if err != nil {
  1083. return fmt.Errorf("Error rehashing config file operclasses: %s", err.Error())
  1084. }
  1085. opers, err := config.Operators(operclasses)
  1086. if err != nil {
  1087. return fmt.Errorf("Error rehashing config file opers: %s", err.Error())
  1088. }
  1089. // TODO: support rehash of existing operator perms?
  1090. // sanity checks complete, start modifying server state
  1091. if initial {
  1092. server.name = config.Server.Name
  1093. server.nameCasefolded = casefoldedName
  1094. }
  1095. server.networkName = config.Network.Name
  1096. server.configurableStateMutex.Lock()
  1097. if config.Server.Password != "" {
  1098. server.password = config.Server.PasswordBytes()
  1099. } else {
  1100. server.password = nil
  1101. }
  1102. server.configurableStateMutex.Unlock()
  1103. // apply new PROXY command restrictions
  1104. server.proxyAllowedFrom = config.Server.ProxyAllowedFrom
  1105. // apply new connectionlimits
  1106. server.connectionLimitsMutex.Lock()
  1107. server.connectionLimits = connectionLimits
  1108. server.connectionThrottleMutex.Lock()
  1109. server.connectionThrottle = connectionThrottle
  1110. server.clients.ByNickMutex.RLock()
  1111. for _, client := range server.clients.ByNick {
  1112. ipaddr := client.IP()
  1113. if ipaddr != nil {
  1114. server.connectionLimits.AddClient(ipaddr, true)
  1115. }
  1116. }
  1117. server.clients.ByNickMutex.RUnlock()
  1118. server.connectionThrottleMutex.Unlock()
  1119. server.connectionLimitsMutex.Unlock()
  1120. // setup new and removed caps
  1121. addedCaps := caps.NewSet()
  1122. removedCaps := caps.NewSet()
  1123. updatedCaps := caps.NewSet()
  1124. // SASL
  1125. if config.Accounts.AuthenticationEnabled && !server.accountAuthenticationEnabled {
  1126. // enabling SASL
  1127. SupportedCapabilities.Enable(caps.SASL)
  1128. CapValues.Set(caps.SASL, "PLAIN,EXTERNAL")
  1129. addedCaps.Add(caps.SASL)
  1130. }
  1131. if !config.Accounts.AuthenticationEnabled && server.accountAuthenticationEnabled {
  1132. // disabling SASL
  1133. SupportedCapabilities.Disable(caps.SASL)
  1134. removedCaps.Add(caps.SASL)
  1135. }
  1136. server.accountAuthenticationEnabled = config.Accounts.AuthenticationEnabled
  1137. // STS
  1138. stsValue := config.Server.STS.Value()
  1139. var stsDisabled bool
  1140. stsCurrentCapValue, _ := CapValues.Get(caps.STS)
  1141. server.logger.Debug("rehash", "STS Vals", stsCurrentCapValue, stsValue, fmt.Sprintf("server[%v] config[%v]", server.stsEnabled, config.Server.STS.Enabled))
  1142. if config.Server.STS.Enabled && !server.stsEnabled {
  1143. // enabling STS
  1144. SupportedCapabilities.Enable(caps.STS)
  1145. addedCaps.Add(caps.STS)
  1146. CapValues.Set(caps.STS, stsValue)
  1147. } else if !config.Server.STS.Enabled && server.stsEnabled {
  1148. // disabling STS
  1149. SupportedCapabilities.Disable(caps.STS)
  1150. removedCaps.Add(caps.STS)
  1151. stsDisabled = true
  1152. } else if config.Server.STS.Enabled && server.stsEnabled && stsValue != stsCurrentCapValue {
  1153. // STS policy updated
  1154. CapValues.Set(caps.STS, stsValue)
  1155. updatedCaps.Add(caps.STS)
  1156. }
  1157. server.stsEnabled = config.Server.STS.Enabled
  1158. // burst new and removed caps
  1159. var capBurstClients ClientSet
  1160. added := make(map[caps.Version]string)
  1161. var removed string
  1162. // updated caps get DEL'd and then NEW'd
  1163. // so, we can just add updated ones to both removed and added lists here and they'll be correctly handled
  1164. server.logger.Debug("rehash", "Updated Caps", updatedCaps.String(caps.Cap301, CapValues), strconv.Itoa(updatedCaps.Count()))
  1165. for _, capab := range updatedCaps.List() {
  1166. addedCaps.Enable(capab)
  1167. removedCaps.Enable(capab)
  1168. }
  1169. if 0 < addedCaps.Count() || 0 < removedCaps.Count() {
  1170. capBurstClients = server.clients.AllWithCaps(caps.CapNotify)
  1171. added[caps.Cap301] = addedCaps.String(caps.Cap301, CapValues)
  1172. added[caps.Cap302] = addedCaps.String(caps.Cap302, CapValues)
  1173. // removed never has values, so we leave it as Cap301
  1174. removed = removedCaps.String(caps.Cap301, CapValues)
  1175. }
  1176. for sClient := range capBurstClients {
  1177. if stsDisabled {
  1178. // remove STS policy
  1179. //TODO(dan): this is an ugly hack. we can write this better.
  1180. stsPolicy := "sts=duration=0"
  1181. if 0 < addedCaps.Count() {
  1182. added[caps.Cap302] = added[caps.Cap302] + " " + stsPolicy
  1183. } else {
  1184. addedCaps.Enable(caps.STS)
  1185. added[caps.Cap302] = stsPolicy
  1186. }
  1187. }
  1188. // DEL caps and then send NEW ones so that updated caps get removed/added correctly
  1189. if 0 < removedCaps.Count() {
  1190. sClient.Send(nil, server.name, "CAP", sClient.nick, "DEL", removed)
  1191. }
  1192. if 0 < addedCaps.Count() {
  1193. sClient.Send(nil, server.name, "CAP", sClient.nick, "NEW", added[sClient.capVersion])
  1194. }
  1195. }
  1196. // set server options
  1197. server.configurableStateMutex.Lock()
  1198. lineLenConfig := LineLenLimits{
  1199. Tags: config.Limits.LineLen.Tags,
  1200. Rest: config.Limits.LineLen.Rest,
  1201. }
  1202. server.limits = Limits{
  1203. AwayLen: int(config.Limits.AwayLen),
  1204. ChannelLen: int(config.Limits.ChannelLen),
  1205. KickLen: int(config.Limits.KickLen),
  1206. MonitorEntries: int(config.Limits.MonitorEntries),
  1207. NickLen: int(config.Limits.NickLen),
  1208. TopicLen: int(config.Limits.TopicLen),
  1209. ChanListModes: int(config.Limits.ChanListModes),
  1210. LineLen: lineLenConfig,
  1211. }
  1212. server.operclasses = *operclasses
  1213. server.operators = opers
  1214. server.checkIdent = config.Server.CheckIdent
  1215. // registration
  1216. accountReg := NewAccountRegistration(config.Accounts.Registration)
  1217. server.accountRegistration = &accountReg
  1218. server.channelRegistrationEnabled = config.Channels.Registration.Enabled
  1219. server.defaultChannelModes = ParseDefaultChannelModes(config)
  1220. server.configurableStateMutex.Unlock()
  1221. // set new sendqueue size
  1222. if config.Server.MaxSendQBytes != server.MaxSendQBytes {
  1223. server.configurableStateMutex.Lock()
  1224. server.MaxSendQBytes = config.Server.MaxSendQBytes
  1225. server.configurableStateMutex.Unlock()
  1226. // update on all clients
  1227. server.clients.ByNickMutex.RLock()
  1228. for _, sClient := range server.clients.ByNick {
  1229. sClient.socket.MaxSendQBytes = config.Server.MaxSendQBytes
  1230. }
  1231. server.clients.ByNickMutex.RUnlock()
  1232. }
  1233. // set RPL_ISUPPORT
  1234. var newISupportReplies [][]string
  1235. oldISupportList := server.isupport
  1236. server.setISupport()
  1237. if oldISupportList != nil {
  1238. newISupportReplies = oldISupportList.GetDifference(server.isupport)
  1239. }
  1240. server.loadMOTD(config.Server.MOTD, config.Server.MOTDFormatting)
  1241. // reload logging config
  1242. err = server.logger.ApplyConfig(config.Logging)
  1243. if err != nil {
  1244. return err
  1245. }
  1246. nowLoggingRawIO := server.logger.IsLoggingRawIO()
  1247. // notify clients if raw i/o logging was enabled by a rehash
  1248. sendRawOutputNotice := !initial && !server.loggingRawIO && nowLoggingRawIO
  1249. server.loggingRawIO = nowLoggingRawIO
  1250. if initial {
  1251. if err := server.loadDatastore(config.Datastore.Path); err != nil {
  1252. return err
  1253. }
  1254. }
  1255. // we are now open for business
  1256. server.setupListeners(config)
  1257. if !initial {
  1258. // push new info to all of our clients
  1259. server.clients.ByNickMutex.RLock()
  1260. for _, sClient := range server.clients.ByNick {
  1261. for _, tokenline := range newISupportReplies {
  1262. sClient.Send(nil, server.name, RPL_ISUPPORT, append([]string{sClient.nick}, tokenline...)...)
  1263. }
  1264. if sendRawOutputNotice {
  1265. sClient.Notice(rawIONotice)
  1266. }
  1267. }
  1268. server.clients.ByNickMutex.RUnlock()
  1269. }
  1270. return nil
  1271. }
  1272. func (server *Server) loadMOTD(motdPath string, useFormatting bool) error {
  1273. server.logger.Debug("rehash", "Loading MOTD")
  1274. motdLines := make([]string, 0)
  1275. if motdPath != "" {
  1276. file, err := os.Open(motdPath)
  1277. if err == nil {
  1278. defer file.Close()
  1279. reader := bufio.NewReader(file)
  1280. for {
  1281. line, err := reader.ReadString('\n')
  1282. if err != nil {
  1283. break
  1284. }
  1285. line = strings.TrimRight(line, "\r\n")
  1286. if useFormatting {
  1287. line = ircfmt.Unescape(line)
  1288. }
  1289. // "- " is the required prefix for MOTD, we just add it here to make
  1290. // bursting it out to clients easier
  1291. line = fmt.Sprintf("- %s", line)
  1292. motdLines = append(motdLines, line)
  1293. }
  1294. } else {
  1295. return err
  1296. }
  1297. }
  1298. server.configurableStateMutex.Lock()
  1299. server.motdLines = motdLines
  1300. server.configurableStateMutex.Unlock()
  1301. return nil
  1302. }
  1303. func (server *Server) loadDatastore(datastorePath string) error {
  1304. // open the datastore and load server state for which it (rather than config)
  1305. // is the source of truth
  1306. server.logger.Debug("startup", "Opening datastore")
  1307. db, err := OpenDatabase(datastorePath)
  1308. if err == nil {
  1309. server.store = db
  1310. } else {
  1311. return fmt.Errorf("Failed to open datastore: %s", err.Error())
  1312. }
  1313. // load *lines (from the datastores)
  1314. server.logger.Debug("startup", "Loading D/Klines")
  1315. server.loadDLines()
  1316. server.loadKLines()
  1317. // load password manager
  1318. server.logger.Debug("startup", "Loading passwords")
  1319. err = server.store.View(func(tx *buntdb.Tx) error {
  1320. saltString, err := tx.Get(keySalt)
  1321. if err != nil {
  1322. return fmt.Errorf("Could not retrieve salt string: %s", err.Error())
  1323. }
  1324. salt, err := base64.StdEncoding.DecodeString(saltString)
  1325. if err != nil {
  1326. return err
  1327. }
  1328. pwm := passwd.NewSaltedManager(salt)
  1329. server.passwords = &pwm
  1330. return nil
  1331. })
  1332. if err != nil {
  1333. return fmt.Errorf("Could not load salt: %s", err.Error())
  1334. }
  1335. return nil
  1336. }
  1337. func (server *Server) setupListeners(config *Config) {
  1338. // update or destroy all existing listeners
  1339. tlsListeners := config.TLSListeners()
  1340. for addr := range server.listeners {
  1341. currentListener := server.listeners[addr]
  1342. var stillConfigured bool
  1343. for _, newaddr := range config.Server.Listen {
  1344. if newaddr == addr {
  1345. stillConfigured = true
  1346. break
  1347. }
  1348. }
  1349. // pass new config information to the listener, to be picked up after
  1350. // its next Accept(). this is like sending over a buffered channel of
  1351. // size 1, but where sending a second item overwrites the buffered item
  1352. // instead of blocking.
  1353. currentListener.configMutex.Lock()
  1354. currentListener.shouldStop = !stillConfigured
  1355. currentListener.tlsConfig = tlsListeners[addr]
  1356. currentListener.configMutex.Unlock()
  1357. if stillConfigured {
  1358. server.logger.Info("listeners",
  1359. fmt.Sprintf("now listening on %s, tls=%t.", addr, (currentListener.tlsConfig != nil)),
  1360. )
  1361. } else {
  1362. // tell the listener it should stop by interrupting its Accept() call:
  1363. currentListener.listener.Close()
  1364. // TODO(golang1.10) delete stopEvent once issue #21856 is released
  1365. <-currentListener.stopEvent
  1366. delete(server.listeners, addr)
  1367. server.logger.Info("listeners", fmt.Sprintf("stopped listening on %s.", addr))
  1368. }
  1369. }
  1370. // create new listeners that were not previously configured
  1371. for _, newaddr := range config.Server.Listen {
  1372. _, exists := server.listeners[newaddr]
  1373. if !exists {
  1374. // make new listener
  1375. server.listeners[newaddr] = server.createListener(newaddr, tlsListeners[newaddr])
  1376. }
  1377. }
  1378. if len(tlsListeners) == 0 {
  1379. 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")
  1380. }
  1381. var usesStandardTLSPort bool
  1382. for addr := range config.TLSListeners() {
  1383. if strings.Contains(addr, "6697") {
  1384. usesStandardTLSPort = true
  1385. break
  1386. }
  1387. }
  1388. if 0 < len(tlsListeners) && !usesStandardTLSPort {
  1389. 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")
  1390. }
  1391. }
  1392. // GetDefaultChannelModes returns our default channel modes.
  1393. func (server *Server) GetDefaultChannelModes() Modes {
  1394. server.configurableStateMutex.RLock()
  1395. defer server.configurableStateMutex.RUnlock()
  1396. return server.defaultChannelModes
  1397. }
  1398. // REHASH
  1399. func rehashHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
  1400. server.logger.Info("rehash", fmt.Sprintf("REHASH command used by %s", client.nick))
  1401. err := server.rehash()
  1402. if err == nil {
  1403. client.Send(nil, server.name, RPL_REHASHING, client.nick, "ircd.yaml", "Rehashing")
  1404. } else {
  1405. server.logger.Error("rehash", fmt.Sprintln("Failed to rehash:", err.Error()))
  1406. client.Send(nil, server.name, ERR_UNKNOWNERROR, client.nick, "REHASH", err.Error())
  1407. }
  1408. return false
  1409. }
  1410. // AWAY [<message>]
  1411. func awayHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
  1412. var isAway bool
  1413. var text string
  1414. if len(msg.Params) > 0 {
  1415. isAway = true
  1416. text = msg.Params[0]
  1417. awayLen := server.getLimits().AwayLen
  1418. if len(text) > awayLen {
  1419. text = text[:awayLen]
  1420. }
  1421. }
  1422. if isAway {
  1423. client.flags[Away] = true
  1424. } else {
  1425. delete(client.flags, Away)
  1426. }
  1427. client.awayMessage = text
  1428. var op ModeOp
  1429. if client.flags[Away] {
  1430. op = Add
  1431. client.Send(nil, server.name, RPL_NOWAWAY, client.nick, "You have been marked as being away")
  1432. } else {
  1433. op = Remove
  1434. client.Send(nil, server.name, RPL_UNAWAY, client.nick, "You are no longer marked as being away")
  1435. }
  1436. //TODO(dan): Should this be sent automagically as part of setting the flag/mode?
  1437. modech := ModeChanges{ModeChange{
  1438. mode: Away,
  1439. op: op,
  1440. }}
  1441. client.Send(nil, server.name, "MODE", client.nick, modech.String())
  1442. // dispatch away-notify
  1443. for friend := range client.Friends(caps.AwayNotify) {
  1444. if client.flags[Away] {
  1445. friend.SendFromClient("", client, nil, "AWAY", client.awayMessage)
  1446. } else {
  1447. friend.SendFromClient("", client, nil, "AWAY")
  1448. }
  1449. }
  1450. return false
  1451. }
  1452. // ISON <nick>{ <nick>}
  1453. func isonHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
  1454. var nicks = msg.Params
  1455. var err error
  1456. var casefoldedNick string
  1457. ison := make([]string, 0)
  1458. for _, nick := range nicks {
  1459. casefoldedNick, err = CasefoldName(nick)
  1460. if err != nil {
  1461. continue
  1462. }
  1463. if iclient := server.clients.Get(casefoldedNick); iclient != nil {
  1464. ison = append(ison, iclient.nick)
  1465. }
  1466. }
  1467. client.Send(nil, server.name, RPL_ISON, client.nick, strings.Join(nicks, " "))
  1468. return false
  1469. }
  1470. // MOTD [<target>]
  1471. func motdHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
  1472. //TODO(dan): hook this up when we have multiple servers I guess???
  1473. //var target string
  1474. //if len(msg.Params) > 0 {
  1475. // target = msg.Params[0]
  1476. //}
  1477. server.MOTD(client)
  1478. return false
  1479. }
  1480. // NOTICE <target>{,<target>} <message>
  1481. func noticeHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
  1482. clientOnlyTags := GetClientOnlyTags(msg.Tags)
  1483. targets := strings.Split(msg.Params[0], ",")
  1484. message := msg.Params[1]
  1485. // split privmsg
  1486. splitMsg := server.splitMessage(message, !client.capabilities.Has(caps.MaxLine))
  1487. for i, targetString := range targets {
  1488. // max of four targets per privmsg
  1489. if i > maxTargets-1 {
  1490. break
  1491. }
  1492. prefixes, targetString := SplitChannelMembershipPrefixes(targetString)
  1493. lowestPrefix := GetLowestChannelModePrefix(prefixes)
  1494. target, cerr := CasefoldChannel(targetString)
  1495. if cerr == nil {
  1496. channel := server.channels.Get(target)
  1497. if channel == nil {
  1498. // errors silently ignored with NOTICE as per RFC
  1499. continue
  1500. }
  1501. if !channel.CanSpeak(client) {
  1502. // errors silently ignored with NOTICE as per RFC
  1503. continue
  1504. }
  1505. msgid := server.generateMessageID()
  1506. channel.SplitNotice(msgid, lowestPrefix, clientOnlyTags, client, splitMsg)
  1507. } else {
  1508. target, err := CasefoldName(targetString)
  1509. if err != nil {
  1510. continue
  1511. }
  1512. if target == "chanserv" {
  1513. server.chanservReceiveNotice(client, message)
  1514. continue
  1515. } else if target == "nickserv" {
  1516. server.nickservReceiveNotice(client, message)
  1517. continue
  1518. }
  1519. user := server.clients.Get(target)
  1520. if user == nil {
  1521. // errors silently ignored with NOTICE as per RFC
  1522. continue
  1523. }
  1524. if !user.capabilities.Has(caps.MessageTags) {
  1525. clientOnlyTags = nil
  1526. }
  1527. msgid := server.generateMessageID()
  1528. // restrict messages appropriately when +R is set
  1529. // intentionally make the sending user think the message went through fine
  1530. if !user.flags[RegisteredOnly] || client.registered {
  1531. user.SendSplitMsgFromClient(msgid, client, clientOnlyTags, "NOTICE", user.nick, splitMsg)
  1532. }
  1533. if client.capabilities.Has(caps.EchoMessage) {
  1534. client.SendSplitMsgFromClient(msgid, client, clientOnlyTags, "NOTICE", user.nick, splitMsg)
  1535. }
  1536. }
  1537. }
  1538. return false
  1539. }
  1540. // KICK <channel>{,<channel>} <user>{,<user>} [<comment>]
  1541. func kickHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
  1542. channels := strings.Split(msg.Params[0], ",")
  1543. users := strings.Split(msg.Params[1], ",")
  1544. if (len(channels) != len(users)) && (len(users) != 1) {
  1545. client.Send(nil, server.name, ERR_NEEDMOREPARAMS, client.nick, "KICK", "Not enough parameters")
  1546. return false
  1547. }
  1548. var kicks [][]string
  1549. for index, channel := range channels {
  1550. if len(users) == 1 {
  1551. kicks = append(kicks, []string{channel, users[0]})
  1552. } else {
  1553. kicks = append(kicks, []string{channel, users[index]})
  1554. }
  1555. }
  1556. var comment string
  1557. if len(msg.Params) > 2 {
  1558. comment = msg.Params[2]
  1559. }
  1560. for _, info := range kicks {
  1561. chname := info[0]
  1562. nickname := info[1]
  1563. casefoldedChname, err := CasefoldChannel(chname)
  1564. channel := server.channels.Get(casefoldedChname)
  1565. if err != nil || channel == nil {
  1566. client.Send(nil, server.name, ERR_NOSUCHCHANNEL, client.nick, chname, "No such channel")
  1567. continue
  1568. }
  1569. casefoldedNickname, err := CasefoldName(nickname)
  1570. target := server.clients.Get(casefoldedNickname)
  1571. if err != nil || target == nil {
  1572. client.Send(nil, server.name, ERR_NOSUCHNICK, client.nick, nickname, "No such nick")
  1573. continue
  1574. }
  1575. // make sure client has privs to kick the given user
  1576. //TODO(dan): split this into a separate function that checks if users have privs
  1577. // over other users, useful for things like -aoh as well
  1578. channel.membersMutex.Lock()
  1579. var hasPrivs bool
  1580. for _, mode := range ChannelPrivModes {
  1581. if channel.members[client][mode] {
  1582. hasPrivs = true
  1583. // admins cannot kick other admins
  1584. if mode == ChannelAdmin && channel.members[target][ChannelAdmin] {
  1585. hasPrivs = false
  1586. }
  1587. break
  1588. } else if channel.members[target][mode] {
  1589. break
  1590. }
  1591. }
  1592. if hasPrivs {
  1593. if comment == "" {
  1594. comment = nickname
  1595. }
  1596. channel.kickNoMutex(client, target, comment)
  1597. } else {
  1598. client.Send(nil, client.server.name, ERR_CHANOPRIVSNEEDED, chname, "You're not a channel operator")
  1599. }
  1600. channel.membersMutex.Unlock()
  1601. }
  1602. return false
  1603. }
  1604. // elistMatcher takes and matches ELIST conditions
  1605. type elistMatcher struct {
  1606. MinClientsActive bool
  1607. MinClients int
  1608. MaxClientsActive bool
  1609. MaxClients int
  1610. }
  1611. // Matches checks whether the given channel matches our matches.
  1612. func (matcher *elistMatcher) Matches(channel *Channel) bool {
  1613. channel.membersMutex.RLock()
  1614. defer channel.membersMutex.RUnlock()
  1615. if matcher.MinClientsActive {
  1616. if len(channel.members) < matcher.MinClients {
  1617. return false
  1618. }
  1619. }
  1620. if matcher.MaxClientsActive {
  1621. if matcher.MaxClients < len(channel.members) {
  1622. return false
  1623. }
  1624. }
  1625. return true
  1626. }
  1627. // LIST [<channel>{,<channel>}] [<elistcond>{,<elistcond>}]
  1628. func listHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
  1629. // get channels
  1630. var channels []string
  1631. for _, param := range msg.Params {
  1632. if 0 < len(param) && param[0] == '#' {
  1633. for _, channame := range strings.Split(param, ",") {
  1634. if 0 < len(channame) && channame[0] == '#' {
  1635. channels = append(channels, channame)
  1636. }
  1637. }
  1638. }
  1639. }
  1640. // get elist conditions
  1641. var matcher elistMatcher
  1642. for _, param := range msg.Params {
  1643. if len(param) < 1 {
  1644. continue
  1645. }
  1646. if param[0] == '<' {
  1647. param = param[1:]
  1648. val, err := strconv.Atoi(param)
  1649. if err != nil {
  1650. continue
  1651. }
  1652. matcher.MaxClientsActive = true
  1653. matcher.MaxClients = val - 1 // -1 because < means less than the given number
  1654. }
  1655. if param[0] == '>' {
  1656. param = param[1:]
  1657. val, err := strconv.Atoi(param)
  1658. if err != nil {
  1659. continue
  1660. }
  1661. matcher.MinClientsActive = true
  1662. matcher.MinClients = val + 1 // +1 because > means more than the given number
  1663. }
  1664. }
  1665. if len(channels) == 0 {
  1666. server.channels.ChansLock.RLock()
  1667. for _, channel := range server.channels.Chans {
  1668. if !client.flags[Operator] && channel.flags[Secret] {
  1669. continue
  1670. }
  1671. if matcher.Matches(channel) {
  1672. client.RplList(channel)
  1673. }
  1674. }
  1675. server.channels.ChansLock.RUnlock()
  1676. } else {
  1677. // limit regular users to only listing one channel
  1678. if !client.flags[Operator] {
  1679. channels = channels[:1]
  1680. }
  1681. for _, chname := range channels {
  1682. casefoldedChname, err := CasefoldChannel(chname)
  1683. channel := server.channels.Get(casefoldedChname)
  1684. if err != nil || channel == nil || (!client.flags[Operator] && channel.flags[Secret]) {
  1685. if len(chname) > 0 {
  1686. client.Send(nil, server.name, ERR_NOSUCHCHANNEL, client.nick, chname, "No such channel")
  1687. }
  1688. continue
  1689. }
  1690. if matcher.Matches(channel) {
  1691. client.RplList(channel)
  1692. }
  1693. }
  1694. }
  1695. client.Send(nil, server.name, RPL_LISTEND, client.nick, "End of LIST")
  1696. return false
  1697. }
  1698. // RplList returns the RPL_LIST numeric for the given channel.
  1699. func (target *Client) RplList(channel *Channel) {
  1700. channel.membersMutex.RLock()
  1701. defer channel.membersMutex.RUnlock()
  1702. // get the correct number of channel members
  1703. var memberCount int
  1704. if target.flags[Operator] || channel.members.Has(target) {
  1705. memberCount = len(channel.members)
  1706. } else {
  1707. for member := range channel.members {
  1708. if !member.flags[Invisible] {
  1709. memberCount++
  1710. }
  1711. }
  1712. }
  1713. target.Send(nil, target.server.name, RPL_LIST, target.nick, channel.name, strconv.Itoa(memberCount), channel.topic)
  1714. }
  1715. // NAMES [<channel>{,<channel>}]
  1716. func namesHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
  1717. var channels []string
  1718. if len(msg.Params) > 0 {
  1719. channels = strings.Split(msg.Params[0], ",")
  1720. }
  1721. //var target string
  1722. //if len(msg.Params) > 1 {
  1723. // target = msg.Params[1]
  1724. //}
  1725. if len(channels) == 0 {
  1726. server.channels.ChansLock.RLock()
  1727. for _, channel := range server.channels.Chans {
  1728. channel.Names(client)
  1729. }
  1730. server.channels.ChansLock.RUnlock()
  1731. return false
  1732. }
  1733. // limit regular users to only listing one channel
  1734. if !client.flags[Operator] {
  1735. channels = channels[:1]
  1736. }
  1737. for _, chname := range channels {
  1738. casefoldedChname, err := CasefoldChannel(chname)
  1739. channel := server.channels.Get(casefoldedChname)
  1740. if err != nil || channel == nil {
  1741. if len(chname) > 0 {
  1742. client.Send(nil, server.name, ERR_NOSUCHCHANNEL, client.nick, chname, "No such channel")
  1743. }
  1744. continue
  1745. }
  1746. channel.Names(client)
  1747. }
  1748. return false
  1749. }
  1750. // VERSION [<server>]
  1751. func versionHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
  1752. var target string
  1753. if len(msg.Params) > 0 {
  1754. target = msg.Params[0]
  1755. }
  1756. casefoldedTarget, err := Casefold(target)
  1757. if target != "" && (err != nil || casefoldedTarget != server.nameCasefolded) {
  1758. client.Send(nil, server.name, ERR_NOSUCHSERVER, client.nick, target, "No such server")
  1759. return false
  1760. }
  1761. client.Send(nil, server.name, RPL_VERSION, client.nick, Ver, server.name)
  1762. client.RplISupport()
  1763. return false
  1764. }
  1765. // INVITE <nickname> <channel>
  1766. func inviteHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
  1767. nickname := msg.Params[0]
  1768. channelName := msg.Params[1]
  1769. casefoldedNickname, err := CasefoldName(nickname)
  1770. target := server.clients.Get(casefoldedNickname)
  1771. if err != nil || target == nil {
  1772. client.Send(nil, server.name, ERR_NOSUCHNICK, client.nick, nickname, "No such nick")
  1773. return false
  1774. }
  1775. casefoldedChannelName, err := CasefoldChannel(channelName)
  1776. channel := server.channels.Get(casefoldedChannelName)
  1777. if err != nil || channel == nil {
  1778. client.Send(nil, server.name, RPL_INVITING, client.nick, target.nick, channelName)
  1779. target.Send(nil, client.nickMaskString, "INVITE", target.nick, channel.name)
  1780. return true
  1781. }
  1782. channel.Invite(target, client)
  1783. return false
  1784. }
  1785. // TIME [<server>]
  1786. func timeHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
  1787. var target string
  1788. if len(msg.Params) > 0 {
  1789. target = msg.Params[0]
  1790. }
  1791. casefoldedTarget, err := Casefold(target)
  1792. if (target != "") && err != nil || (casefoldedTarget != server.nameCasefolded) {
  1793. client.Send(nil, server.name, ERR_NOSUCHSERVER, client.nick, target, "No such server")
  1794. return false
  1795. }
  1796. client.Send(nil, server.name, RPL_TIME, client.nick, server.name, time.Now().Format(time.RFC1123))
  1797. return false
  1798. }
  1799. // KILL <nickname> <comment>
  1800. func killHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
  1801. nickname := msg.Params[0]
  1802. comment := "<no reason supplied>"
  1803. if len(msg.Params) > 1 {
  1804. comment = msg.Params[1]
  1805. }
  1806. casefoldedNickname, err := CasefoldName(nickname)
  1807. target := server.clients.Get(casefoldedNickname)
  1808. if err != nil || target == nil {
  1809. client.Send(nil, client.server.name, ERR_NOSUCHNICK, client.nick, nickname, "No such nick")
  1810. return false
  1811. }
  1812. quitMsg := fmt.Sprintf("Killed (%s (%s))", client.nick, comment)
  1813. 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))
  1814. target.exitedSnomaskSent = true
  1815. target.Quit(quitMsg)
  1816. target.destroy()
  1817. return false
  1818. }
  1819. // WHOWAS <nickname> [<count> [<server>]]
  1820. func whowasHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
  1821. nicknames := strings.Split(msg.Params[0], ",")
  1822. var count int64
  1823. if len(msg.Params) > 1 {
  1824. count, _ = strconv.ParseInt(msg.Params[1], 10, 64)
  1825. }
  1826. //var target string
  1827. //if len(msg.Params) > 2 {
  1828. // target = msg.Params[2]
  1829. //}
  1830. for _, nickname := range nicknames {
  1831. results := server.whoWas.Find(nickname, count)
  1832. if len(results) == 0 {
  1833. if len(nickname) > 0 {
  1834. client.Send(nil, server.name, ERR_WASNOSUCHNICK, client.nick, nickname, "There was no such nickname")
  1835. }
  1836. } else {
  1837. for _, whoWas := range results {
  1838. client.Send(nil, server.name, RPL_WHOWASUSER, client.nick, whoWas.nickname, whoWas.username, whoWas.hostname, "*", whoWas.realname)
  1839. }
  1840. }
  1841. if len(nickname) > 0 {
  1842. client.Send(nil, server.name, RPL_ENDOFWHOWAS, client.nick, nickname, "End of WHOWAS")
  1843. }
  1844. }
  1845. return false
  1846. }
  1847. // LUSERS [<mask> [<server>]]
  1848. func lusersHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
  1849. //TODO(vegax87) Fix network statistics and additional parameters
  1850. var totalcount, invisiblecount, opercount int
  1851. server.clients.ByNickMutex.RLock()
  1852. defer server.clients.ByNickMutex.RUnlock()
  1853. for _, onlineusers := range server.clients.ByNick {
  1854. totalcount++
  1855. if onlineusers.flags[Invisible] {
  1856. invisiblecount++
  1857. }
  1858. if onlineusers.flags[Operator] {
  1859. opercount++
  1860. }
  1861. }
  1862. 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))
  1863. client.Send(nil, server.name, RPL_LUSEROP, client.nick, fmt.Sprintf("%d IRC Operators online", opercount))
  1864. client.Send(nil, server.name, RPL_LUSERCHANNELS, client.nick, fmt.Sprintf("%d channels formed", server.channels.Len()))
  1865. client.Send(nil, server.name, RPL_LUSERME, client.nick, fmt.Sprintf("I have %d clients and %d servers", totalcount, 1))
  1866. return false
  1867. }
  1868. // USERHOST <nickname> [<nickname> <nickname> ...]
  1869. func userhostHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
  1870. returnedNicks := make(map[string]bool)
  1871. for i, nickname := range msg.Params {
  1872. if i >= 10 {
  1873. break
  1874. }
  1875. casefoldedNickname, err := CasefoldName(nickname)
  1876. target := server.clients.Get(casefoldedNickname)
  1877. if err != nil || target == nil {
  1878. client.Send(nil, client.server.name, ERR_NOSUCHNICK, client.nick, nickname, "No such nick")
  1879. return false
  1880. }
  1881. if returnedNicks[casefoldedNickname] {
  1882. continue
  1883. }
  1884. // to prevent returning multiple results for a single nick
  1885. returnedNicks[casefoldedNickname] = true
  1886. var isOper, isAway string
  1887. if target.flags[Operator] {
  1888. isOper = "*"
  1889. }
  1890. if target.flags[Away] {
  1891. isAway = "-"
  1892. } else {
  1893. isAway = "+"
  1894. }
  1895. 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))
  1896. }
  1897. return false
  1898. }
  1899. // PROXY TCP4/6 SOURCEIP DESTIP SOURCEPORT DESTPORT
  1900. // http://www.haproxy.org/download/1.8/doc/proxy-protocol.txt
  1901. func proxyHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
  1902. // only allow unregistered clients to use this command
  1903. if client.registered {
  1904. return false
  1905. }
  1906. clientAddress := utils.IPString(client.socket.conn.RemoteAddr())
  1907. clientHostname := client.hostname
  1908. for _, address := range server.proxyAllowedFrom {
  1909. if clientHostname == address || clientAddress == address {
  1910. proxiedIP := msg.Params[1]
  1911. // ensure IP is sane
  1912. parsedProxiedIP := net.ParseIP(proxiedIP)
  1913. if parsedProxiedIP == nil {
  1914. client.Quit(fmt.Sprintf("Proxied IP address is not valid: [%s]", proxiedIP))
  1915. return true
  1916. }
  1917. isBanned, banMsg := server.checkBans(parsedProxiedIP)
  1918. if isBanned {
  1919. client.Quit(banMsg)
  1920. return true
  1921. }
  1922. // override the client's regular IP
  1923. client.proxiedIP = msg.Params[1]
  1924. client.rawHostname = utils.LookupHostname(msg.Params[1])
  1925. client.hostname = client.rawHostname
  1926. return false
  1927. }
  1928. }
  1929. client.Quit("PROXY command is not usable from your address")
  1930. return true
  1931. }