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

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957
  1. // Copyright (c) 2012-2014 Jeremy Latt
  2. // Copyright (c) 2014-2015 Edmund Huber
  3. // Copyright (c) 2016- 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. "net/http"
  16. "os"
  17. "os/signal"
  18. "strconv"
  19. "strings"
  20. "sync"
  21. "syscall"
  22. "time"
  23. "github.com/DanielOaks/girc-go/ircmsg"
  24. "github.com/tidwall/buntdb"
  25. )
  26. var (
  27. // cached because this may be used lots
  28. tooManyClientsMsg = ircmsg.MakeMessage(nil, "", "ERROR", "Too many clients from your network")
  29. tooManyClientsBytes, _ = tooManyClientsMsg.Line()
  30. bannedFromServerMsg = ircmsg.MakeMessage(nil, "", "ERROR", "You are banned from this server (%s)")
  31. bannedFromServerBytes, _ = bannedFromServerMsg.Line()
  32. errDbOutOfDate = errors.New("Database schema is old")
  33. )
  34. // Limits holds the maximum limits for various things such as topic lengths.
  35. type Limits struct {
  36. AwayLen int
  37. ChannelLen int
  38. KickLen int
  39. MonitorEntries int
  40. NickLen int
  41. TopicLen int
  42. ChanListModes int
  43. LineLen LineLenLimits
  44. }
  45. // LineLenLimits holds the maximum limits for IRC lines.
  46. type LineLenLimits struct {
  47. Tags int
  48. Rest int
  49. }
  50. // ListenerInterface represents an interface for a listener.
  51. type ListenerInterface struct {
  52. Listener net.Listener
  53. Events chan ListenerEvent
  54. }
  55. const (
  56. // DestroyListener instructs the listener to destroy itself.
  57. DestroyListener ListenerEventType = iota
  58. // UpdateListener instructs the listener to update itself (grab new certs, etc).
  59. UpdateListener = iota
  60. )
  61. // ListenerEventType is the type of event this is.
  62. type ListenerEventType int
  63. // ListenerEvent is an event that's passed to the listener.
  64. type ListenerEvent struct {
  65. Type ListenerEventType
  66. NewConfig *tls.Config
  67. }
  68. // Server is the main Oragono server.
  69. type Server struct {
  70. accountAuthenticationEnabled bool
  71. accountRegistration *AccountRegistration
  72. accounts map[string]*ClientAccount
  73. channels ChannelNameMap
  74. checkIdent bool
  75. clients *ClientLookupSet
  76. commands chan Command
  77. configFilename string
  78. connectionLimits *ConnectionLimits
  79. connectionLimitsMutex sync.Mutex // used when affecting the connection limiter, to make sure rehashing doesn't make things go out-of-whack
  80. connectionThrottle *ConnectionThrottle
  81. connectionThrottleMutex sync.Mutex // used when affecting the connection limiter, to make sure rehashing doesn't make things go out-of-whack
  82. ctime time.Time
  83. currentOpers map[*Client]bool
  84. dlines *DLineManager
  85. idle chan *Client
  86. isupport *ISupportList
  87. klines *KLineManager
  88. limits Limits
  89. listenerEventActMutex sync.Mutex
  90. listeners map[string]ListenerInterface
  91. listenerUpdateMutex sync.Mutex
  92. logger *Logger
  93. monitoring map[string][]Client
  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 *PasswordManager
  103. rehashMutex sync.Mutex
  104. rehashSignal chan os.Signal
  105. restAPI *RestAPIConfig
  106. signals chan os.Signal
  107. store *buntdb.DB
  108. stsEnabled bool
  109. whoWas *WhoWasList
  110. }
  111. var (
  112. // ServerExitSignals are the signals the server will exit on.
  113. ServerExitSignals = []os.Signal{
  114. syscall.SIGINT,
  115. syscall.SIGTERM,
  116. syscall.SIGQUIT,
  117. }
  118. )
  119. type clientConn struct {
  120. Conn net.Conn
  121. IsTLS bool
  122. }
  123. // NewServer returns a new Oragono server.
  124. func NewServer(configFilename string, config *Config, logger *Logger) (*Server, error) {
  125. casefoldedName, err := Casefold(config.Server.Name)
  126. if err != nil {
  127. return nil, fmt.Errorf("Server name isn't valid [%s]: %s", config.Server.Name, err.Error())
  128. }
  129. // startup check that we have HELP entries for every command
  130. for name := range Commands {
  131. _, exists := Help[strings.ToLower(name)]
  132. if !exists {
  133. return nil, fmt.Errorf("Help entry does not exist for command %s", name)
  134. }
  135. }
  136. if config.Accounts.AuthenticationEnabled {
  137. SupportedCapabilities[SASL] = true
  138. }
  139. if config.Server.STS.Enabled {
  140. SupportedCapabilities[STS] = true
  141. CapValues[STS] = config.Server.STS.Value()
  142. }
  143. if config.Limits.LineLen.Tags > 512 || config.Limits.LineLen.Rest > 512 {
  144. SupportedCapabilities[MaxLine] = true
  145. CapValues[MaxLine] = fmt.Sprintf("%d,%d", config.Limits.LineLen.Tags, config.Limits.LineLen.Rest)
  146. }
  147. operClasses, err := config.OperatorClasses()
  148. if err != nil {
  149. return nil, fmt.Errorf("Error loading oper classes: %s", err.Error())
  150. }
  151. opers, err := config.Operators(operClasses)
  152. if err != nil {
  153. return nil, fmt.Errorf("Error loading operators: %s", err.Error())
  154. }
  155. connectionLimits, err := NewConnectionLimits(config.Server.ConnectionLimits)
  156. if err != nil {
  157. return nil, fmt.Errorf("Error loading connection limits: %s", err.Error())
  158. }
  159. connectionThrottle, err := NewConnectionThrottle(config.Server.ConnectionThrottle)
  160. if err != nil {
  161. return nil, fmt.Errorf("Error loading connection throttler: %s", err.Error())
  162. }
  163. server := &Server{
  164. accounts: make(map[string]*ClientAccount),
  165. accountAuthenticationEnabled: config.Accounts.AuthenticationEnabled,
  166. channels: make(ChannelNameMap),
  167. clients: NewClientLookupSet(),
  168. commands: make(chan Command),
  169. configFilename: configFilename,
  170. connectionLimits: connectionLimits,
  171. connectionThrottle: connectionThrottle,
  172. ctime: time.Now(),
  173. currentOpers: make(map[*Client]bool),
  174. idle: make(chan *Client),
  175. limits: Limits{
  176. AwayLen: int(config.Limits.AwayLen),
  177. ChannelLen: int(config.Limits.ChannelLen),
  178. KickLen: int(config.Limits.KickLen),
  179. MonitorEntries: int(config.Limits.MonitorEntries),
  180. NickLen: int(config.Limits.NickLen),
  181. TopicLen: int(config.Limits.TopicLen),
  182. ChanListModes: int(config.Limits.ChanListModes),
  183. LineLen: LineLenLimits{
  184. Tags: config.Limits.LineLen.Tags,
  185. Rest: config.Limits.LineLen.Rest,
  186. },
  187. },
  188. listeners: make(map[string]ListenerInterface),
  189. logger: logger,
  190. monitoring: make(map[string][]Client),
  191. name: config.Server.Name,
  192. nameCasefolded: casefoldedName,
  193. networkName: config.Network.Name,
  194. newConns: make(chan clientConn),
  195. operclasses: *operClasses,
  196. operators: opers,
  197. signals: make(chan os.Signal, len(ServerExitSignals)),
  198. stsEnabled: config.Server.STS.Enabled,
  199. rehashSignal: make(chan os.Signal, 1),
  200. restAPI: &config.Server.RestAPI,
  201. whoWas: NewWhoWasList(config.Limits.WhowasEntries),
  202. checkIdent: config.Server.CheckIdent,
  203. }
  204. // open data store
  205. server.logger.Log(LogDebug, "startup", "Opening datastore")
  206. db, err := buntdb.Open(config.Datastore.Path)
  207. if err != nil {
  208. return nil, fmt.Errorf("Failed to open datastore: %s", err.Error())
  209. }
  210. server.store = db
  211. // check db version
  212. err = server.store.View(func(tx *buntdb.Tx) error {
  213. version, _ := tx.Get(keySchemaVersion)
  214. if version != latestDbSchema {
  215. logger.Log(LogError, "startup", "server", fmt.Sprintf("Database must be updated. Expected schema v%s, got v%s.", latestDbSchema, version))
  216. return errDbOutOfDate
  217. }
  218. return nil
  219. })
  220. if err != nil {
  221. // close the db
  222. db.Close()
  223. return nil, errDbOutOfDate
  224. }
  225. // load *lines
  226. server.logger.Log(LogDebug, "startup", "Loading D/Klines")
  227. server.loadDLines()
  228. server.loadKLines()
  229. // load password manager
  230. server.logger.Log(LogDebug, "startup", "Loading passwords")
  231. err = server.store.View(func(tx *buntdb.Tx) error {
  232. saltString, err := tx.Get(keySalt)
  233. if err != nil {
  234. return fmt.Errorf("Could not retrieve salt string: %s", err.Error())
  235. }
  236. salt, err := base64.StdEncoding.DecodeString(saltString)
  237. if err != nil {
  238. return err
  239. }
  240. pwm := NewPasswordManager(salt)
  241. server.passwords = &pwm
  242. return nil
  243. })
  244. if err != nil {
  245. return nil, fmt.Errorf("Could not load salt: %s", err.Error())
  246. }
  247. server.logger.Log(LogDebug, "startup", "Loading MOTD")
  248. if config.Server.MOTD != "" {
  249. file, err := os.Open(config.Server.MOTD)
  250. if err == nil {
  251. defer file.Close()
  252. reader := bufio.NewReader(file)
  253. for {
  254. line, err := reader.ReadString('\n')
  255. if err != nil {
  256. break
  257. }
  258. line = strings.TrimRight(line, "\r\n")
  259. // "- " is the required prefix for MOTD, we just add it here to make
  260. // bursting it out to clients easier
  261. line = fmt.Sprintf("- %s", line)
  262. server.motdLines = append(server.motdLines, line)
  263. }
  264. }
  265. }
  266. if config.Server.Password != "" {
  267. server.password = config.Server.PasswordBytes()
  268. }
  269. for _, addr := range config.Server.Listen {
  270. server.createListener(addr, config.TLSListeners())
  271. }
  272. if config.Server.Wslisten != "" {
  273. server.wslisten(config.Server.Wslisten, config.Server.TLSListeners)
  274. }
  275. // registration
  276. accountReg := NewAccountRegistration(config.Accounts.Registration)
  277. server.accountRegistration = &accountReg
  278. // Attempt to clean up when receiving these signals.
  279. signal.Notify(server.signals, ServerExitSignals...)
  280. signal.Notify(server.rehashSignal, syscall.SIGHUP)
  281. server.setISupport()
  282. // start API if enabled
  283. if server.restAPI.Enabled {
  284. logger.Log(LogInfo, "startup", "server", fmt.Sprintf("%s rest API started on %s.", server.name, server.restAPI.Listen))
  285. server.startRestAPI()
  286. }
  287. return server, nil
  288. }
  289. // setISupport sets up our RPL_ISUPPORT reply.
  290. func (server *Server) setISupport() {
  291. maxTargetsString := strconv.Itoa(maxTargets)
  292. // add RPL_ISUPPORT tokens
  293. server.isupport = NewISupportList()
  294. server.isupport.Add("AWAYLEN", strconv.Itoa(server.limits.AwayLen))
  295. server.isupport.Add("CASEMAPPING", casemappingName)
  296. server.isupport.Add("CHANMODES", strings.Join([]string{ChannelModes{BanMask, ExceptMask, InviteMask}.String(), "", ChannelModes{UserLimit, Key}.String(), ChannelModes{InviteOnly, Moderated, NoOutside, OpOnlyTopic, ChanRoleplaying, Secret}.String()}, ","))
  297. server.isupport.Add("CHANNELLEN", strconv.Itoa(server.limits.ChannelLen))
  298. server.isupport.Add("CHANTYPES", "#")
  299. server.isupport.Add("EXCEPTS", "")
  300. server.isupport.Add("INVEX", "")
  301. server.isupport.Add("KICKLEN", strconv.Itoa(server.limits.KickLen))
  302. server.isupport.Add("MAXLIST", fmt.Sprintf("beI:%s", strconv.Itoa(server.limits.ChanListModes)))
  303. server.isupport.Add("MAXTARGETS", maxTargetsString)
  304. server.isupport.Add("MODES", "")
  305. server.isupport.Add("MONITOR", strconv.Itoa(server.limits.MonitorEntries))
  306. server.isupport.Add("NETWORK", server.networkName)
  307. server.isupport.Add("NICKLEN", strconv.Itoa(server.limits.NickLen))
  308. server.isupport.Add("PREFIX", "(qaohv)~&@%+")
  309. server.isupport.Add("RPCHAN", "E")
  310. server.isupport.Add("RPUSER", "E")
  311. server.isupport.Add("STATUSMSG", "~&@%+")
  312. server.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))
  313. server.isupport.Add("TOPICLEN", strconv.Itoa(server.limits.TopicLen))
  314. // account registration
  315. if server.accountRegistration.Enabled {
  316. // 'none' isn't shown in the REGCALLBACKS vars
  317. var enabledCallbacks []string
  318. for _, name := range server.accountRegistration.EnabledCallbacks {
  319. if name != "*" {
  320. enabledCallbacks = append(enabledCallbacks, name)
  321. }
  322. }
  323. server.isupport.Add("REGCOMMANDS", "CREATE,VERIFY")
  324. server.isupport.Add("REGCALLBACKS", strings.Join(enabledCallbacks, ","))
  325. server.isupport.Add("REGCREDTYPES", "passphrase,certfp")
  326. }
  327. server.isupport.RegenerateCachedReply()
  328. }
  329. func loadChannelList(channel *Channel, list string, maskMode ChannelMode) {
  330. if list == "" {
  331. return
  332. }
  333. channel.lists[maskMode].AddAll(strings.Split(list, " "))
  334. }
  335. // Shutdown shuts down the server.
  336. func (server *Server) Shutdown() {
  337. //TODO(dan): Make sure we disallow new nicks
  338. server.clients.ByNickMutex.RLock()
  339. for _, client := range server.clients.ByNick {
  340. client.Notice("Server is shutting down")
  341. }
  342. server.clients.ByNickMutex.RUnlock()
  343. if err := server.store.Close(); err != nil {
  344. server.logger.Log(LogError, "shutdown", fmt.Sprintln("Could not close datastore:", err))
  345. }
  346. }
  347. // Run starts the server.
  348. func (server *Server) Run() {
  349. // defer closing db/store
  350. defer server.store.Close()
  351. done := false
  352. for !done {
  353. select {
  354. case <-server.signals:
  355. server.Shutdown()
  356. done = true
  357. case <-server.rehashSignal:
  358. server.logger.Log(LogInfo, "rehash", "Rehashing due to SIGHUP")
  359. err := server.rehash()
  360. if err != nil {
  361. server.logger.Log(LogError, "rehash", fmt.Sprintln("Failed to rehash:", err.Error()))
  362. }
  363. case conn := <-server.newConns:
  364. // check connection limits
  365. ipaddr := net.ParseIP(IPString(conn.Conn.RemoteAddr()))
  366. if ipaddr != nil {
  367. // check DLINEs
  368. isBanned, info := server.dlines.CheckIP(ipaddr)
  369. if isBanned {
  370. banMessage := fmt.Sprintf(bannedFromServerBytes, info.Reason)
  371. if info.Time != nil {
  372. banMessage += fmt.Sprintf(" [%s]", info.Time.Duration.String())
  373. }
  374. conn.Conn.Write([]byte(banMessage))
  375. conn.Conn.Close()
  376. continue
  377. }
  378. // check connection limits
  379. server.connectionLimitsMutex.Lock()
  380. err := server.connectionLimits.AddClient(ipaddr, false)
  381. server.connectionLimitsMutex.Unlock()
  382. if err != nil {
  383. // too many connections from one client, tell the client and close the connection
  384. // 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
  385. conn.Conn.Write([]byte(tooManyClientsBytes))
  386. conn.Conn.Close()
  387. continue
  388. }
  389. // check connection throttle
  390. server.connectionThrottleMutex.Lock()
  391. err = server.connectionThrottle.AddClient(ipaddr)
  392. server.connectionThrottleMutex.Unlock()
  393. if err != nil {
  394. // too many connections too quickly from client, tell them and close the connection
  395. length := &IPRestrictTime{
  396. Duration: server.connectionThrottle.BanDuration,
  397. Expires: time.Now().Add(server.connectionThrottle.BanDuration),
  398. }
  399. server.dlines.AddIP(ipaddr, length, server.connectionThrottle.BanMessage, "Exceeded automated connection throttle")
  400. // reset ban on connectionThrottle
  401. server.connectionThrottle.ResetFor(ipaddr)
  402. // 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
  403. conn.Conn.Write([]byte(server.connectionThrottle.BanMessageBytes))
  404. conn.Conn.Close()
  405. continue
  406. }
  407. server.logger.Log(LogDebug, "localconnect-ip", fmt.Sprintf("Client connecting from %v", ipaddr))
  408. go NewClient(server, conn.Conn, conn.IsTLS)
  409. continue
  410. }
  411. case client := <-server.idle:
  412. client.Idle()
  413. }
  414. }
  415. }
  416. //
  417. // IRC protocol listeners
  418. //
  419. // createListener starts the given listeners.
  420. func (server *Server) createListener(addr string, tlsMap map[string]*tls.Config) {
  421. config, listenTLS := tlsMap[addr]
  422. _, alreadyExists := server.listeners[addr]
  423. if alreadyExists {
  424. log.Fatal(server, "listener already exists:", addr)
  425. }
  426. // make listener event channel
  427. listenerEventChannel := make(chan ListenerEvent, 1)
  428. // make listener
  429. listener, err := net.Listen("tcp", addr)
  430. if err != nil {
  431. log.Fatal(server, "listen error: ", err)
  432. }
  433. tlsString := "plaintext"
  434. if listenTLS {
  435. config.ClientAuth = tls.RequestClientCert
  436. listener = tls.NewListener(listener, config)
  437. tlsString = "TLS"
  438. }
  439. // throw our details to the server so we can be modified/killed later
  440. li := ListenerInterface{
  441. Events: listenerEventChannel,
  442. Listener: listener,
  443. }
  444. server.listeners[addr] = li
  445. // start listening
  446. server.logger.Log(LogInfo, "listeners", fmt.Sprintf("listening on %s using %s.", addr, tlsString))
  447. // setup accept goroutine
  448. go func() {
  449. for {
  450. conn, err := listener.Accept()
  451. if err == nil {
  452. newConn := clientConn{
  453. Conn: conn,
  454. IsTLS: listenTLS,
  455. }
  456. server.newConns <- newConn
  457. }
  458. select {
  459. case event := <-server.listeners[addr].Events:
  460. // this is used to confirm that whoever passed us this event has closed the existing listener correctly (in an attempt to get us to notice the event).
  461. // this is required to keep REHASH from having a very small race possibility of killing the primary listener
  462. server.listenerEventActMutex.Lock()
  463. server.listenerEventActMutex.Unlock()
  464. if event.Type == DestroyListener {
  465. // listener should already be closed, this is just for safety
  466. listener.Close()
  467. return
  468. } else if event.Type == UpdateListener {
  469. // close old listener
  470. listener.Close()
  471. // make new listener
  472. listener, err = net.Listen("tcp", addr)
  473. if err != nil {
  474. log.Fatal(server, "listen error: ", err)
  475. }
  476. tlsString := "plaintext"
  477. if event.NewConfig != nil {
  478. config = event.NewConfig
  479. config.ClientAuth = tls.RequestClientCert
  480. listener = tls.NewListener(listener, config)
  481. tlsString = "TLS"
  482. }
  483. // update server ListenerInterface
  484. li.Listener = listener
  485. server.listenerUpdateMutex.Lock()
  486. server.listeners[addr] = li
  487. server.listenerUpdateMutex.Unlock()
  488. // print notice
  489. server.logger.Log(LogInfo, "listeners", fmt.Sprintf("updated listener %s using %s.", addr, tlsString))
  490. }
  491. default:
  492. // no events waiting for us, fall-through and continue
  493. }
  494. }
  495. }()
  496. }
  497. //
  498. // websocket listen goroutine
  499. //
  500. func (server *Server) wslisten(addr string, tlsMap map[string]*TLSListenConfig) {
  501. http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
  502. if r.Method != "GET" {
  503. server.logger.Log(LogError, "ws", addr, fmt.Sprintf("%s method not allowed", r.Method))
  504. return
  505. }
  506. // We don't have any subprotocols, so if someone attempts to `new
  507. // WebSocket(server, "subprotocol")` they'll break here, instead of
  508. // getting the default, ambiguous, response from gorilla.
  509. if v, ok := r.Header["Sec-Websocket-Protocol"]; ok {
  510. http.Error(w, fmt.Sprintf("WebSocket subprocotols (e.g. %s) not supported", v), 400)
  511. }
  512. ws, err := upgrader.Upgrade(w, r, nil)
  513. if err != nil {
  514. server.logger.Log(LogError, "ws", addr, fmt.Sprintf("%s websocket upgrade error: %s", server.name, err))
  515. return
  516. }
  517. newConn := clientConn{
  518. Conn: WSContainer{ws},
  519. IsTLS: false, //TODO(dan): track TLS or not here properly
  520. }
  521. server.newConns <- newConn
  522. })
  523. go func() {
  524. config, listenTLS := tlsMap[addr]
  525. tlsString := "plaintext"
  526. var err error
  527. if listenTLS {
  528. tlsString = "TLS"
  529. }
  530. server.logger.Log(LogInfo, "listeners", fmt.Sprintf("websocket listening on %s using %s.", addr, tlsString))
  531. if listenTLS {
  532. err = http.ListenAndServeTLS(addr, config.Cert, config.Key, nil)
  533. } else {
  534. err = http.ListenAndServe(addr, nil)
  535. }
  536. if err != nil {
  537. server.logger.Log(LogError, "listeners", fmt.Sprintf("listenAndServe error [%s]: %s", tlsString, err))
  538. }
  539. }()
  540. }
  541. // generateMessageID returns a network-unique message ID.
  542. func (server *Server) generateMessageID() string {
  543. return fmt.Sprintf("%s-%s", strconv.FormatInt(time.Now().UTC().UnixNano(), 10), strconv.FormatInt(rand.Int63(), 10))
  544. }
  545. //
  546. // server functionality
  547. //
  548. func (server *Server) tryRegister(c *Client) {
  549. if c.registered || !c.HasNick() || !c.HasUsername() ||
  550. (c.capState == CapNegotiating) {
  551. return
  552. }
  553. // check KLINEs
  554. isBanned, info := server.klines.CheckMasks(c.AllNickmasks()...)
  555. if isBanned {
  556. reason := info.Reason
  557. if info.Time != nil {
  558. reason += fmt.Sprintf(" [%s]", info.Time.Duration.String())
  559. }
  560. c.Send(nil, "", "ERROR", fmt.Sprintf("You are banned from this server (%s)", reason))
  561. c.quitMessageSent = true
  562. c.destroy()
  563. return
  564. }
  565. // continue registration
  566. server.logger.Log(LogDebug, "localconnect", fmt.Sprintf("Client registered [%s]", c.nick))
  567. c.Register()
  568. // send welcome text
  569. //NOTE(dan): we specifically use the NICK here instead of the nickmask
  570. // see http://modern.ircdocs.horse/#rplwelcome-001 for details on why we avoid using the nickmask
  571. c.Send(nil, server.name, RPL_WELCOME, c.nick, fmt.Sprintf("Welcome to the Internet Relay Network %s", c.nick))
  572. c.Send(nil, server.name, RPL_YOURHOST, c.nick, fmt.Sprintf("Your host is %s, running version %s", server.name, Ver))
  573. c.Send(nil, server.name, RPL_CREATED, c.nick, fmt.Sprintf("This server was created %s", server.ctime.Format(time.RFC1123)))
  574. //TODO(dan): Look at adding last optional [<channel modes with a parameter>] parameter
  575. c.Send(nil, server.name, RPL_MYINFO, c.nick, server.name, Ver, supportedUserModesString, supportedChannelModesString)
  576. c.RplISupport()
  577. server.MOTD(c)
  578. c.Send(nil, c.nickMaskString, RPL_UMODEIS, c.nick, c.ModeString())
  579. if server.logger.DumpingRawInOut {
  580. c.Notice("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.")
  581. }
  582. }
  583. // MOTD serves the Message of the Day.
  584. func (server *Server) MOTD(client *Client) {
  585. if len(server.motdLines) < 1 {
  586. client.Send(nil, server.name, ERR_NOMOTD, client.nick, "MOTD File is missing")
  587. return
  588. }
  589. client.Send(nil, server.name, RPL_MOTDSTART, client.nick, fmt.Sprintf("- %s Message of the day - ", server.name))
  590. for _, line := range server.motdLines {
  591. client.Send(nil, server.name, RPL_MOTD, client.nick, line)
  592. }
  593. client.Send(nil, server.name, RPL_ENDOFMOTD, client.nick, "End of MOTD command")
  594. }
  595. //
  596. // registration commands
  597. //
  598. // PASS <password>
  599. func passHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
  600. if client.registered {
  601. client.Send(nil, server.name, ERR_ALREADYREGISTRED, client.nick, "You may not reregister")
  602. return false
  603. }
  604. // if no password exists, skip checking
  605. if len(server.password) == 0 {
  606. client.authorized = true
  607. return false
  608. }
  609. // check the provided password
  610. password := []byte(msg.Params[0])
  611. if ComparePassword(server.password, password) != nil {
  612. client.Send(nil, server.name, ERR_PASSWDMISMATCH, client.nick, "Password incorrect")
  613. client.Send(nil, server.name, "ERROR", "Password incorrect")
  614. return true
  615. }
  616. client.authorized = true
  617. return false
  618. }
  619. // USER <username> * 0 <realname>
  620. func userHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
  621. if client.registered {
  622. client.Send(nil, server.name, ERR_ALREADYREGISTRED, client.nick, "You may not reregister")
  623. return false
  624. }
  625. if !client.authorized {
  626. client.Quit("Bad password")
  627. return true
  628. }
  629. if client.username != "" && client.realname != "" {
  630. return false
  631. }
  632. // confirm that username is valid
  633. //
  634. _, err := CasefoldName(msg.Params[0])
  635. if err != nil {
  636. client.Send(nil, "", "ERROR", "Malformed username")
  637. return true
  638. }
  639. if !client.HasUsername() {
  640. client.username = "~" + msg.Params[0]
  641. // don't bother updating nickmask here, it's not valid anyway
  642. }
  643. if client.realname == "" {
  644. client.realname = msg.Params[3]
  645. }
  646. server.tryRegister(client)
  647. return false
  648. }
  649. // QUIT [<reason>]
  650. func quitHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
  651. reason := "Quit"
  652. if len(msg.Params) > 0 {
  653. reason += ": " + msg.Params[0]
  654. }
  655. client.Quit(reason)
  656. return true
  657. }
  658. //
  659. // normal commands
  660. //
  661. // PING <server1> [<server2>]
  662. func pingHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
  663. client.Send(nil, server.name, "PONG", msg.Params...)
  664. return false
  665. }
  666. // PONG <server> [ <server2> ]
  667. func pongHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
  668. // client gets touched when they send this command, so we don't need to do anything
  669. return false
  670. }
  671. // JOIN <channel>{,<channel>} [<key>{,<key>}]
  672. // JOIN 0
  673. func joinHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
  674. // handle JOIN 0
  675. if msg.Params[0] == "0" {
  676. for channel := range client.channels {
  677. channel.Part(client, client.nickCasefolded)
  678. }
  679. return false
  680. }
  681. // handle regular JOINs
  682. channels := strings.Split(msg.Params[0], ",")
  683. var keys []string
  684. if len(msg.Params) > 1 {
  685. keys = strings.Split(msg.Params[1], ",")
  686. }
  687. for i, name := range channels {
  688. casefoldedName, err := CasefoldChannel(name)
  689. if err != nil {
  690. if len(name) > 0 {
  691. client.Send(nil, server.name, ERR_NOSUCHCHANNEL, client.nick, name, "No such channel")
  692. }
  693. continue
  694. }
  695. channel := server.channels.Get(casefoldedName)
  696. if channel == nil {
  697. if len(casefoldedName) > server.limits.ChannelLen {
  698. client.Send(nil, server.name, ERR_NOSUCHCHANNEL, client.nick, name, "No such channel")
  699. continue
  700. }
  701. channel = NewChannel(server, name, true)
  702. }
  703. var key string
  704. if len(keys) > i {
  705. key = keys[i]
  706. }
  707. channel.Join(client, key)
  708. }
  709. return false
  710. }
  711. // PART <channel>{,<channel>} [<reason>]
  712. func partHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
  713. channels := strings.Split(msg.Params[0], ",")
  714. 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
  715. if len(msg.Params) > 1 {
  716. reason = msg.Params[1]
  717. }
  718. for _, chname := range channels {
  719. casefoldedChannelName, err := CasefoldChannel(chname)
  720. channel := server.channels.Get(casefoldedChannelName)
  721. if err != nil || channel == nil {
  722. if len(chname) > 0 {
  723. client.Send(nil, server.name, ERR_NOSUCHCHANNEL, client.nick, chname, "No such channel")
  724. }
  725. continue
  726. }
  727. channel.Part(client, reason)
  728. }
  729. return false
  730. }
  731. // TOPIC <channel> [<topic>]
  732. func topicHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
  733. name, err := CasefoldChannel(msg.Params[0])
  734. channel := server.channels.Get(name)
  735. if err != nil || channel == nil {
  736. if len(msg.Params[0]) > 0 {
  737. client.Send(nil, server.name, ERR_NOSUCHCHANNEL, client.nick, msg.Params[0], "No such channel")
  738. }
  739. return false
  740. }
  741. if len(msg.Params) > 1 {
  742. channel.SetTopic(client, msg.Params[1])
  743. } else {
  744. channel.GetTopic(client)
  745. }
  746. return false
  747. }
  748. func wordWrap(text string, lineWidth int) []string {
  749. var lines []string
  750. var cacheLine, cacheWord string
  751. for _, char := range text {
  752. if (char == ' ' || char == '-') && len(cacheLine)+len(cacheWord)+1 < lineWidth {
  753. cacheLine += cacheWord + string(char)
  754. cacheWord = ""
  755. } else if len(cacheLine)+len(cacheWord)+1 >= lineWidth {
  756. if len(cacheLine) < (lineWidth / 2) {
  757. // there must be a really long word or something, just split on word boundary
  758. cacheLine += cacheWord + string(char)
  759. cacheWord = ""
  760. }
  761. lines = append(lines, cacheLine)
  762. cacheLine = ""
  763. } else {
  764. cacheWord += string(char)
  765. }
  766. }
  767. if len(cacheWord) > 0 {
  768. cacheLine += cacheWord
  769. }
  770. if len(cacheLine) > 0 {
  771. lines = append(lines, cacheLine)
  772. }
  773. return lines
  774. }
  775. // SplitMessage represents a message that's been split for sending.
  776. type SplitMessage struct {
  777. For512 []string
  778. ForMaxLine string
  779. }
  780. func (server *Server) splitMessage(original string, origIs512 bool) SplitMessage {
  781. var newSplit SplitMessage
  782. newSplit.ForMaxLine = original
  783. if !origIs512 {
  784. newSplit.For512 = wordWrap(original, 400)
  785. } else {
  786. newSplit.For512 = []string{original}
  787. }
  788. return newSplit
  789. }
  790. // PRIVMSG <target>{,<target>} <message>
  791. func privmsgHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
  792. clientOnlyTags := GetClientOnlyTags(msg.Tags)
  793. targets := strings.Split(msg.Params[0], ",")
  794. message := msg.Params[1]
  795. // split privmsg
  796. splitMsg := server.splitMessage(message, !client.capabilities[MaxLine])
  797. for i, targetString := range targets {
  798. // max of four targets per privmsg
  799. if i > maxTargets-1 {
  800. break
  801. }
  802. prefixes, targetString := SplitChannelMembershipPrefixes(targetString)
  803. lowestPrefix := GetLowestChannelModePrefix(prefixes)
  804. // eh, no need to notify them
  805. if len(targetString) < 1 {
  806. continue
  807. }
  808. target, err := CasefoldChannel(targetString)
  809. if err == nil {
  810. channel := server.channels.Get(target)
  811. if channel == nil {
  812. client.Send(nil, server.name, ERR_NOSUCHCHANNEL, client.nick, targetString, "No such channel")
  813. continue
  814. }
  815. msgid := server.generateMessageID()
  816. channel.SplitPrivMsg(msgid, lowestPrefix, clientOnlyTags, client, splitMsg)
  817. } else {
  818. target, err = CasefoldName(targetString)
  819. user := server.clients.Get(target)
  820. if err != nil || user == nil {
  821. if len(target) > 0 {
  822. client.Send(nil, server.name, ERR_NOSUCHNICK, target, "No such nick")
  823. }
  824. continue
  825. }
  826. if !user.capabilities[MessageTags] {
  827. clientOnlyTags = nil
  828. }
  829. msgid := server.generateMessageID()
  830. user.SendSplitMsgFromClient(msgid, client, clientOnlyTags, "PRIVMSG", user.nick, splitMsg)
  831. if client.capabilities[EchoMessage] {
  832. client.SendSplitMsgFromClient(msgid, client, clientOnlyTags, "PRIVMSG", user.nick, splitMsg)
  833. }
  834. if user.flags[Away] {
  835. //TODO(dan): possibly implement cooldown of away notifications to users
  836. client.Send(nil, server.name, RPL_AWAY, user.nick, user.awayMessage)
  837. }
  838. }
  839. }
  840. return false
  841. }
  842. // TAGMSG <target>{,<target>}
  843. func tagmsgHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
  844. clientOnlyTags := GetClientOnlyTags(msg.Tags)
  845. // no client-only tags, so we can drop it
  846. if clientOnlyTags == nil {
  847. return false
  848. }
  849. targets := strings.Split(msg.Params[0], ",")
  850. for i, targetString := range targets {
  851. // max of four targets per privmsg
  852. if i > maxTargets-1 {
  853. break
  854. }
  855. prefixes, targetString := SplitChannelMembershipPrefixes(targetString)
  856. lowestPrefix := GetLowestChannelModePrefix(prefixes)
  857. // eh, no need to notify them
  858. if len(targetString) < 1 {
  859. continue
  860. }
  861. target, err := CasefoldChannel(targetString)
  862. if err == nil {
  863. channel := server.channels.Get(target)
  864. if channel == nil {
  865. client.Send(nil, server.name, ERR_NOSUCHCHANNEL, client.nick, targetString, "No such channel")
  866. continue
  867. }
  868. msgid := server.generateMessageID()
  869. channel.TagMsg(msgid, lowestPrefix, clientOnlyTags, client)
  870. } else {
  871. target, err = CasefoldName(targetString)
  872. user := server.clients.Get(target)
  873. if err != nil || user == nil {
  874. if len(target) > 0 {
  875. client.Send(nil, server.name, ERR_NOSUCHNICK, target, "No such nick")
  876. }
  877. continue
  878. }
  879. msgid := server.generateMessageID()
  880. // end user can't receive tagmsgs
  881. if !user.capabilities[MessageTags] {
  882. continue
  883. }
  884. user.SendFromClient(msgid, client, clientOnlyTags, "TAGMSG", user.nick)
  885. if client.capabilities[EchoMessage] {
  886. client.SendFromClient(msgid, client, clientOnlyTags, "TAGMSG", user.nick)
  887. }
  888. if user.flags[Away] {
  889. //TODO(dan): possibly implement cooldown of away notifications to users
  890. client.Send(nil, server.name, RPL_AWAY, user.nick, user.awayMessage)
  891. }
  892. }
  893. }
  894. return false
  895. }
  896. // WhoisChannelsNames returns the common channel names between two users.
  897. func (client *Client) WhoisChannelsNames(target *Client) []string {
  898. isMultiPrefix := target.capabilities[MultiPrefix]
  899. var chstrs []string
  900. index := 0
  901. for channel := range client.channels {
  902. channel.membersMutex.RLock()
  903. defer channel.membersMutex.RUnlock()
  904. // channel is secret and the target can't see it
  905. if !target.flags[Operator] && channel.flags[Secret] && !channel.members.Has(target) {
  906. continue
  907. }
  908. chstrs = append(chstrs, channel.members[client].Prefixes(isMultiPrefix)+channel.name)
  909. index++
  910. }
  911. return chstrs
  912. }
  913. // WHOIS [ <target> ] <mask> *( "," <mask> )
  914. func whoisHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
  915. var masksString string
  916. //var target string
  917. if len(msg.Params) > 1 {
  918. //target = msg.Params[0]
  919. masksString = msg.Params[1]
  920. } else {
  921. masksString = msg.Params[0]
  922. }
  923. if len(strings.TrimSpace(masksString)) < 1 {
  924. client.Send(nil, server.name, ERR_UNKNOWNERROR, client.nick, msg.Command, "No masks given")
  925. return false
  926. }
  927. if client.flags[Operator] {
  928. masks := strings.Split(masksString, ",")
  929. for _, mask := range masks {
  930. casefoldedMask, err := Casefold(mask)
  931. if err != nil {
  932. client.Send(nil, client.server.name, ERR_NOSUCHNICK, mask, "No such nick")
  933. continue
  934. }
  935. matches := server.clients.FindAll(casefoldedMask)
  936. if len(matches) == 0 {
  937. client.Send(nil, client.server.name, ERR_NOSUCHNICK, mask, "No such nick")
  938. continue
  939. }
  940. for mclient := range matches {
  941. client.getWhoisOf(mclient)
  942. }
  943. }
  944. } else {
  945. // only get the first request
  946. casefoldedMask, err := Casefold(strings.Split(masksString, ",")[0])
  947. mclient := server.clients.Get(casefoldedMask)
  948. if err != nil || mclient == nil {
  949. client.Send(nil, client.server.name, ERR_NOSUCHNICK, masksString, "No such nick")
  950. // fall through, ENDOFWHOIS is always sent
  951. } else {
  952. client.getWhoisOf(mclient)
  953. }
  954. }
  955. client.Send(nil, server.name, RPL_ENDOFWHOIS, client.nick, masksString, "End of /WHOIS list")
  956. return false
  957. }
  958. func (client *Client) getWhoisOf(target *Client) {
  959. client.Send(nil, client.server.name, RPL_WHOISUSER, client.nick, target.nick, target.username, target.hostname, "*", target.realname)
  960. whoischannels := client.WhoisChannelsNames(target)
  961. if whoischannels != nil {
  962. client.Send(nil, client.server.name, RPL_WHOISCHANNELS, client.nick, target.nick, strings.Join(whoischannels, " "))
  963. }
  964. if target.class != nil {
  965. client.Send(nil, client.server.name, RPL_WHOISOPERATOR, client.nick, target.nick, target.whoisLine)
  966. }
  967. if target.certfp != "" && (client.flags[Operator] || client == target) {
  968. client.Send(nil, client.server.name, RPL_WHOISCERTFP, client.nick, target.nick, fmt.Sprintf("has client certificate fingerprint %s", target.certfp))
  969. }
  970. 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")
  971. }
  972. // RplWhoReply returns the WHO reply between one user and another channel/user.
  973. // <channel> <user> <host> <server> <nick> ( "H" / "G" ) ["*"] [ ( "@" / "+" ) ]
  974. // :<hopcount> <real name>
  975. func (target *Client) RplWhoReply(channel *Channel, client *Client) {
  976. channelName := "*"
  977. flags := ""
  978. if client.flags[Away] {
  979. flags = "G"
  980. } else {
  981. flags = "H"
  982. }
  983. if client.flags[Operator] {
  984. flags += "*"
  985. }
  986. if channel != nil {
  987. channel.membersMutex.RLock()
  988. defer channel.membersMutex.RUnlock()
  989. flags += channel.members[client].Prefixes(target.capabilities[MultiPrefix])
  990. channelName = channel.name
  991. }
  992. 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)
  993. }
  994. func whoChannel(client *Client, channel *Channel, friends ClientSet) {
  995. channel.membersMutex.RLock()
  996. defer channel.membersMutex.RUnlock()
  997. for member := range channel.members {
  998. if !client.flags[Invisible] || friends[client] {
  999. client.RplWhoReply(channel, member)
  1000. }
  1001. }
  1002. }
  1003. // WHO [ <mask> [ "o" ] ]
  1004. func whoHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
  1005. friends := client.Friends()
  1006. var mask string
  1007. if len(msg.Params) > 0 {
  1008. casefoldedMask, err := Casefold(msg.Params[0])
  1009. if err != nil {
  1010. client.Send(nil, server.name, ERR_UNKNOWNERROR, "WHO", "Mask isn't valid")
  1011. return false
  1012. }
  1013. mask = casefoldedMask
  1014. }
  1015. //TODO(dan): is this used and would I put this param in the Modern doc?
  1016. // if not, can we remove it?
  1017. //var operatorOnly bool
  1018. //if len(msg.Params) > 1 && msg.Params[1] == "o" {
  1019. // operatorOnly = true
  1020. //}
  1021. if mask == "" {
  1022. for _, channel := range server.channels {
  1023. whoChannel(client, channel, friends)
  1024. }
  1025. } else if mask[0] == '#' {
  1026. // TODO implement wildcard matching
  1027. //TODO(dan): ^ only for opers
  1028. channel := server.channels.Get(mask)
  1029. if channel != nil {
  1030. whoChannel(client, channel, friends)
  1031. }
  1032. } else {
  1033. for mclient := range server.clients.FindAll(mask) {
  1034. client.RplWhoReply(nil, mclient)
  1035. }
  1036. }
  1037. client.Send(nil, server.name, RPL_ENDOFWHO, client.nick, mask, "End of WHO list")
  1038. return false
  1039. }
  1040. // OPER <name> <password>
  1041. func operHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
  1042. name, err := CasefoldName(msg.Params[0])
  1043. if err != nil {
  1044. client.Send(nil, server.name, ERR_PASSWDMISMATCH, client.nick, "Password incorrect")
  1045. return true
  1046. }
  1047. hash := server.operators[name].Pass
  1048. password := []byte(msg.Params[1])
  1049. err = ComparePassword(hash, password)
  1050. if (hash == nil) || (err != nil) {
  1051. client.Send(nil, server.name, ERR_PASSWDMISMATCH, client.nick, "Password incorrect")
  1052. return true
  1053. }
  1054. client.flags[Operator] = true
  1055. client.operName = name
  1056. client.class = server.operators[name].Class
  1057. server.currentOpers[client] = true
  1058. client.whoisLine = server.operators[name].WhoisLine
  1059. // push new vhost if one is set
  1060. if len(server.operators[name].Vhost) > 0 {
  1061. for fClient := range client.Friends(ChgHost) {
  1062. fClient.SendFromClient("", client, nil, "CHGHOST", client.username, server.operators[name].Vhost)
  1063. }
  1064. // CHGHOST requires prefix nickmask to have original hostname, so do that before updating nickmask
  1065. client.vhost = server.operators[name].Vhost
  1066. client.updateNickMask()
  1067. }
  1068. client.Send(nil, server.name, RPL_YOUREOPER, client.nick, "You are now an IRC operator")
  1069. //TODO(dan): Should this be sent automagically as part of setting the flag/mode?
  1070. modech := ModeChanges{&ModeChange{
  1071. mode: Operator,
  1072. op: Add,
  1073. }}
  1074. client.Send(nil, server.name, "MODE", client.nick, modech.String())
  1075. return false
  1076. }
  1077. // rehash reloads the config and applies the changes from the config file.
  1078. func (server *Server) rehash() error {
  1079. server.logger.Log(LogDebug, "rehash", "Starting rehash")
  1080. // only let one REHASH go on at a time
  1081. server.rehashMutex.Lock()
  1082. defer server.rehashMutex.Unlock()
  1083. server.logger.Log(LogDebug, "rehash", "Got rehash lock")
  1084. config, err := LoadConfig(server.configFilename)
  1085. if err != nil {
  1086. return fmt.Errorf("Error rehashing config file config: %s", err.Error())
  1087. }
  1088. // line lengths cannot be changed after launching the server
  1089. if server.limits.LineLen.Tags != config.Limits.LineLen.Tags || server.limits.LineLen.Rest != config.Limits.LineLen.Rest {
  1090. return fmt.Errorf("Maximum line length (linelen) cannot be changed after launching the server, rehash aborted")
  1091. }
  1092. // confirm connectionLimits are fine
  1093. connectionLimits, err := NewConnectionLimits(config.Server.ConnectionLimits)
  1094. if err != nil {
  1095. return fmt.Errorf("Error rehashing config file connection-limits: %s", err.Error())
  1096. }
  1097. // confirm connectionThrottler is fine
  1098. connectionThrottle, err := NewConnectionThrottle(config.Server.ConnectionThrottle)
  1099. if err != nil {
  1100. return fmt.Errorf("Error rehashing config file connection-throttle: %s", err.Error())
  1101. }
  1102. // confirm operator stuff all exists and is fine
  1103. operclasses, err := config.OperatorClasses()
  1104. if err != nil {
  1105. return fmt.Errorf("Error rehashing config file operclasses: %s", err.Error())
  1106. }
  1107. opers, err := config.Operators(operclasses)
  1108. if err != nil {
  1109. return fmt.Errorf("Error rehashing config file opers: %s", err.Error())
  1110. }
  1111. for client := range server.currentOpers {
  1112. _, exists := opers[client.operName]
  1113. if !exists {
  1114. return fmt.Errorf("Oper [%s] no longer exists (used by client [%s])", client.operName, client.nickMaskString)
  1115. }
  1116. }
  1117. // apply new connectionlimits
  1118. server.connectionLimitsMutex.Lock()
  1119. server.connectionLimits = connectionLimits
  1120. server.connectionThrottleMutex.Lock()
  1121. server.connectionThrottle = connectionThrottle
  1122. server.clients.ByNickMutex.RLock()
  1123. for _, client := range server.clients.ByNick {
  1124. ipaddr := net.ParseIP(IPString(client.socket.conn.RemoteAddr()))
  1125. if ipaddr != nil {
  1126. server.connectionLimits.AddClient(ipaddr, true)
  1127. }
  1128. }
  1129. server.clients.ByNickMutex.RUnlock()
  1130. server.connectionThrottleMutex.Unlock()
  1131. server.connectionLimitsMutex.Unlock()
  1132. // setup new and removed caps
  1133. addedCaps := make(CapabilitySet)
  1134. removedCaps := make(CapabilitySet)
  1135. updatedCaps := make(CapabilitySet)
  1136. // SASL
  1137. if config.Accounts.AuthenticationEnabled && !server.accountAuthenticationEnabled {
  1138. // enabling SASL
  1139. SupportedCapabilities[SASL] = true
  1140. addedCaps[SASL] = true
  1141. }
  1142. if !config.Accounts.AuthenticationEnabled && server.accountAuthenticationEnabled {
  1143. // disabling SASL
  1144. SupportedCapabilities[SASL] = false
  1145. removedCaps[SASL] = true
  1146. }
  1147. server.accountAuthenticationEnabled = config.Accounts.AuthenticationEnabled
  1148. // STS
  1149. stsValue := config.Server.STS.Value()
  1150. var stsDisabled bool
  1151. server.logger.Log(LogDebug, "rehash", "STS Vals", CapValues[STS], stsValue, fmt.Sprintf("server[%v] config[%v]", server.stsEnabled, config.Server.STS.Enabled))
  1152. if config.Server.STS.Enabled && !server.stsEnabled {
  1153. // enabling STS
  1154. SupportedCapabilities[STS] = true
  1155. addedCaps[STS] = true
  1156. CapValues[STS] = stsValue
  1157. } else if !config.Server.STS.Enabled && server.stsEnabled {
  1158. // disabling STS
  1159. SupportedCapabilities[STS] = false
  1160. removedCaps[STS] = true
  1161. stsDisabled = true
  1162. } else if config.Server.STS.Enabled && server.stsEnabled && stsValue != CapValues[STS] {
  1163. // STS policy updated
  1164. CapValues[STS] = stsValue
  1165. updatedCaps[STS] = true
  1166. }
  1167. server.stsEnabled = config.Server.STS.Enabled
  1168. // burst new and removed caps
  1169. var capBurstClients ClientSet
  1170. added := make(map[CapVersion]string)
  1171. var removed string
  1172. // updated caps get DEL'd and then NEW'd
  1173. // so, we can just add updated ones to both removed and added lists here and they'll be correctly handled
  1174. server.logger.Log(LogDebug, "rehash", "Updated Caps", updatedCaps.String(Cap301), strconv.Itoa(len(updatedCaps)))
  1175. if len(updatedCaps) > 0 {
  1176. for capab := range updatedCaps {
  1177. addedCaps[capab] = true
  1178. removedCaps[capab] = true
  1179. }
  1180. }
  1181. if len(addedCaps) > 0 || len(removedCaps) > 0 {
  1182. capBurstClients = server.clients.AllWithCaps(CapNotify)
  1183. added[Cap301] = addedCaps.String(Cap301)
  1184. added[Cap302] = addedCaps.String(Cap302)
  1185. // removed never has values
  1186. removed = removedCaps.String(Cap301)
  1187. }
  1188. for sClient := range capBurstClients {
  1189. if stsDisabled {
  1190. // remove STS policy
  1191. //TODO(dan): this is an ugly hack. we can write this better.
  1192. stsPolicy := "sts=duration=0"
  1193. if len(addedCaps) > 0 {
  1194. added[Cap302] = added[Cap302] + " " + stsPolicy
  1195. } else {
  1196. addedCaps[STS] = true
  1197. added[Cap302] = stsPolicy
  1198. }
  1199. }
  1200. if len(removedCaps) > 0 {
  1201. sClient.Send(nil, server.name, "CAP", sClient.nick, "DEL", removed)
  1202. }
  1203. if len(addedCaps) > 0 {
  1204. sClient.Send(nil, server.name, "CAP", sClient.nick, "NEW", added[sClient.capVersion])
  1205. }
  1206. }
  1207. // set server options
  1208. lineLenConfig := LineLenLimits{
  1209. Tags: config.Limits.LineLen.Tags,
  1210. Rest: config.Limits.LineLen.Rest,
  1211. }
  1212. server.limits = Limits{
  1213. AwayLen: int(config.Limits.AwayLen),
  1214. ChannelLen: int(config.Limits.ChannelLen),
  1215. KickLen: int(config.Limits.KickLen),
  1216. MonitorEntries: int(config.Limits.MonitorEntries),
  1217. NickLen: int(config.Limits.NickLen),
  1218. TopicLen: int(config.Limits.TopicLen),
  1219. ChanListModes: int(config.Limits.ChanListModes),
  1220. LineLen: lineLenConfig,
  1221. }
  1222. server.operclasses = *operclasses
  1223. server.operators = opers
  1224. server.checkIdent = config.Server.CheckIdent
  1225. // registration
  1226. accountReg := NewAccountRegistration(config.Accounts.Registration)
  1227. server.accountRegistration = &accountReg
  1228. // set RPL_ISUPPORT
  1229. oldISupportList := server.isupport
  1230. server.setISupport()
  1231. newISupportReplies := oldISupportList.GetDifference(server.isupport)
  1232. // push new info to all of our clients
  1233. server.clients.ByNickMutex.RLock()
  1234. for _, sClient := range server.clients.ByNick {
  1235. for _, tokenline := range newISupportReplies {
  1236. // ugly trickery ahead
  1237. sClient.Send(nil, server.name, RPL_ISUPPORT, append([]string{sClient.nick}, tokenline...)...)
  1238. }
  1239. }
  1240. server.clients.ByNickMutex.RUnlock()
  1241. // destroy old listeners
  1242. tlsListeners := config.TLSListeners()
  1243. for addr := range server.listeners {
  1244. var exists bool
  1245. for _, newaddr := range config.Server.Listen {
  1246. if newaddr == addr {
  1247. exists = true
  1248. break
  1249. }
  1250. }
  1251. server.listenerEventActMutex.Lock()
  1252. if exists {
  1253. // update old listener
  1254. server.listeners[addr].Events <- ListenerEvent{
  1255. Type: UpdateListener,
  1256. NewConfig: tlsListeners[addr],
  1257. }
  1258. } else {
  1259. // destroy nonexistent listener
  1260. server.listeners[addr].Events <- ListenerEvent{
  1261. Type: DestroyListener,
  1262. }
  1263. }
  1264. // force listener to apply the event right away
  1265. server.listeners[addr].Listener.Close()
  1266. server.listenerEventActMutex.Unlock()
  1267. }
  1268. for _, newaddr := range config.Server.Listen {
  1269. _, exists := server.listeners[newaddr]
  1270. if !exists {
  1271. // make new listener
  1272. server.createListener(newaddr, tlsListeners)
  1273. }
  1274. }
  1275. return nil
  1276. }
  1277. // REHASH
  1278. func rehashHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
  1279. server.logger.Log(LogInfo, "rehash", fmt.Sprintf("REHASH command used by %s", client.nick))
  1280. err := server.rehash()
  1281. if err == nil {
  1282. client.Send(nil, server.name, RPL_REHASHING, client.nick, "ircd.yaml", "Rehashing")
  1283. } else {
  1284. server.logger.Log(LogError, "rehash", fmt.Sprintln("Failed to rehash:", err.Error()))
  1285. client.Send(nil, server.name, ERR_UNKNOWNERROR, client.nick, "REHASH", err.Error())
  1286. }
  1287. return false
  1288. }
  1289. // AWAY [<message>]
  1290. func awayHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
  1291. var isAway bool
  1292. var text string
  1293. if len(msg.Params) > 0 {
  1294. isAway = true
  1295. text = msg.Params[0]
  1296. if len(text) > server.limits.AwayLen {
  1297. text = text[:server.limits.AwayLen]
  1298. }
  1299. }
  1300. if isAway {
  1301. client.flags[Away] = true
  1302. } else {
  1303. delete(client.flags, Away)
  1304. }
  1305. client.awayMessage = text
  1306. var op ModeOp
  1307. if client.flags[Away] {
  1308. op = Add
  1309. client.Send(nil, server.name, RPL_NOWAWAY, client.nick, "You have been marked as being away")
  1310. } else {
  1311. op = Remove
  1312. client.Send(nil, server.name, RPL_UNAWAY, client.nick, "You are no longer marked as being away")
  1313. }
  1314. //TODO(dan): Should this be sent automagically as part of setting the flag/mode?
  1315. modech := ModeChanges{&ModeChange{
  1316. mode: Away,
  1317. op: op,
  1318. }}
  1319. client.Send(nil, server.name, "MODE", client.nick, client.nick, modech.String())
  1320. // dispatch away-notify
  1321. for friend := range client.Friends(AwayNotify) {
  1322. if client.flags[Away] {
  1323. friend.SendFromClient("", client, nil, "AWAY", client.awayMessage)
  1324. } else {
  1325. friend.SendFromClient("", client, nil, "AWAY")
  1326. }
  1327. }
  1328. return false
  1329. }
  1330. // ISON <nick>{ <nick>}
  1331. func isonHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
  1332. var nicks = msg.Params
  1333. var err error
  1334. var casefoldedNick string
  1335. ison := make([]string, 0)
  1336. for _, nick := range nicks {
  1337. casefoldedNick, err = CasefoldName(nick)
  1338. if err != nil {
  1339. continue
  1340. }
  1341. if iclient := server.clients.Get(casefoldedNick); iclient != nil {
  1342. ison = append(ison, iclient.nick)
  1343. }
  1344. }
  1345. client.Send(nil, server.name, RPL_ISON, client.nick, strings.Join(nicks, " "))
  1346. return false
  1347. }
  1348. // MOTD [<target>]
  1349. func motdHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
  1350. //TODO(dan): hook this up when we have multiple servers I guess???
  1351. //var target string
  1352. //if len(msg.Params) > 0 {
  1353. // target = msg.Params[0]
  1354. //}
  1355. server.MOTD(client)
  1356. return false
  1357. }
  1358. // NOTICE <target>{,<target>} <message>
  1359. func noticeHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
  1360. clientOnlyTags := GetClientOnlyTags(msg.Tags)
  1361. targets := strings.Split(msg.Params[0], ",")
  1362. message := msg.Params[1]
  1363. // split privmsg
  1364. splitMsg := server.splitMessage(message, !client.capabilities[MaxLine])
  1365. for i, targetString := range targets {
  1366. // max of four targets per privmsg
  1367. if i > maxTargets-1 {
  1368. break
  1369. }
  1370. prefixes, targetString := SplitChannelMembershipPrefixes(targetString)
  1371. lowestPrefix := GetLowestChannelModePrefix(prefixes)
  1372. target, cerr := CasefoldChannel(targetString)
  1373. if cerr == nil {
  1374. channel := server.channels.Get(target)
  1375. if channel == nil {
  1376. // errors silently ignored with NOTICE as per RFC
  1377. continue
  1378. }
  1379. msgid := server.generateMessageID()
  1380. channel.SplitNotice(msgid, lowestPrefix, clientOnlyTags, client, splitMsg)
  1381. } else {
  1382. target, err := CasefoldName(targetString)
  1383. if err != nil {
  1384. continue
  1385. }
  1386. user := server.clients.Get(target)
  1387. if user == nil {
  1388. // errors silently ignored with NOTICE as per RFC
  1389. continue
  1390. }
  1391. if !user.capabilities[MessageTags] {
  1392. clientOnlyTags = nil
  1393. }
  1394. msgid := server.generateMessageID()
  1395. user.SendSplitMsgFromClient(msgid, client, clientOnlyTags, "NOTICE", user.nick, splitMsg)
  1396. if client.capabilities[EchoMessage] {
  1397. client.SendSplitMsgFromClient(msgid, client, clientOnlyTags, "NOTICE", user.nick, splitMsg)
  1398. }
  1399. }
  1400. }
  1401. return false
  1402. }
  1403. // KICK <channel>{,<channel>} <user>{,<user>} [<comment>]
  1404. func kickHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
  1405. channels := strings.Split(msg.Params[0], ",")
  1406. users := strings.Split(msg.Params[1], ",")
  1407. if (len(channels) != len(users)) && (len(users) != 1) {
  1408. client.Send(nil, server.name, ERR_NEEDMOREPARAMS, client.nick, "KICK", "Not enough parameters")
  1409. return false
  1410. }
  1411. var kicks [][]string
  1412. for index, channel := range channels {
  1413. if len(users) == 1 {
  1414. kicks = append(kicks, []string{channel, users[0]})
  1415. } else {
  1416. kicks = append(kicks, []string{channel, users[index]})
  1417. }
  1418. }
  1419. var comment string
  1420. if len(msg.Params) > 2 {
  1421. comment = msg.Params[2]
  1422. }
  1423. for _, info := range kicks {
  1424. chname := info[0]
  1425. nickname := info[1]
  1426. casefoldedChname, err := CasefoldChannel(chname)
  1427. channel := server.channels.Get(casefoldedChname)
  1428. if err != nil || channel == nil {
  1429. client.Send(nil, server.name, ERR_NOSUCHCHANNEL, client.nick, chname, "No such channel")
  1430. continue
  1431. }
  1432. casefoldedNickname, err := CasefoldName(nickname)
  1433. target := server.clients.Get(casefoldedNickname)
  1434. if err != nil || target == nil {
  1435. client.Send(nil, server.name, ERR_NOSUCHNICK, nickname, "No such nick")
  1436. continue
  1437. }
  1438. // make sure client has privs to kick the given user
  1439. //TODO(dan): split this into a separate function that checks if users have privs
  1440. // over other users, useful for things like -aoh as well
  1441. channel.membersMutex.Lock()
  1442. var hasPrivs bool
  1443. for _, mode := range ChannelPrivModes {
  1444. if channel.members[client][mode] {
  1445. hasPrivs = true
  1446. // admins cannot kick other admins
  1447. if mode == ChannelAdmin && channel.members[target][ChannelAdmin] {
  1448. hasPrivs = false
  1449. }
  1450. break
  1451. } else if channel.members[target][mode] {
  1452. break
  1453. }
  1454. }
  1455. if hasPrivs {
  1456. if comment == "" {
  1457. comment = nickname
  1458. }
  1459. channel.kickNoMutex(client, target, comment)
  1460. } else {
  1461. client.Send(nil, client.server.name, ERR_CHANOPRIVSNEEDED, chname, "You're not a channel operator")
  1462. }
  1463. channel.membersMutex.Unlock()
  1464. }
  1465. return false
  1466. }
  1467. // LIST [<channel>{,<channel>} [<server>]]
  1468. func listHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
  1469. var channels []string
  1470. if len(msg.Params) > 0 {
  1471. channels = strings.Split(msg.Params[0], ",")
  1472. }
  1473. var target string
  1474. if len(msg.Params) > 1 {
  1475. target = msg.Params[1]
  1476. }
  1477. //TODO(dan): target server when we have multiple servers
  1478. //TODO(dan): we should continue just fine if it's this current server though
  1479. if target != "" {
  1480. client.Send(nil, server.name, ERR_NOSUCHSERVER, client.nick, target, "No such server")
  1481. return false
  1482. }
  1483. if len(channels) == 0 {
  1484. for _, channel := range server.channels {
  1485. if !client.flags[Operator] && channel.flags[Secret] {
  1486. continue
  1487. }
  1488. client.RplList(channel)
  1489. }
  1490. } else {
  1491. // limit regular users to only listing one channel
  1492. if !client.flags[Operator] {
  1493. channels = channels[:1]
  1494. }
  1495. for _, chname := range channels {
  1496. casefoldedChname, err := CasefoldChannel(chname)
  1497. channel := server.channels.Get(casefoldedChname)
  1498. if err != nil || channel == nil || (!client.flags[Operator] && channel.flags[Secret]) {
  1499. if len(chname) > 0 {
  1500. client.Send(nil, server.name, ERR_NOSUCHCHANNEL, client.nick, chname, "No such channel")
  1501. }
  1502. continue
  1503. }
  1504. client.RplList(channel)
  1505. }
  1506. }
  1507. client.Send(nil, server.name, RPL_LISTEND, client.nick, "End of LIST")
  1508. return false
  1509. }
  1510. func (target *Client) RplList(channel *Channel) {
  1511. channel.membersMutex.RLock()
  1512. defer channel.membersMutex.RUnlock()
  1513. // get the correct number of channel members
  1514. var memberCount int
  1515. if target.flags[Operator] || channel.members.Has(target) {
  1516. memberCount = len(channel.members)
  1517. } else {
  1518. for member := range channel.members {
  1519. if !member.flags[Invisible] {
  1520. memberCount++
  1521. }
  1522. }
  1523. }
  1524. target.Send(nil, target.server.name, RPL_LIST, target.nick, channel.name, strconv.Itoa(memberCount), channel.topic)
  1525. }
  1526. // NAMES [<channel>{,<channel>}]
  1527. func namesHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
  1528. var channels []string
  1529. if len(msg.Params) > 0 {
  1530. channels = strings.Split(msg.Params[0], ",")
  1531. }
  1532. //var target string
  1533. //if len(msg.Params) > 1 {
  1534. // target = msg.Params[1]
  1535. //}
  1536. if len(channels) == 0 {
  1537. for _, channel := range server.channels {
  1538. channel.Names(client)
  1539. }
  1540. return false
  1541. }
  1542. // limit regular users to only listing one channel
  1543. if !client.flags[Operator] {
  1544. channels = channels[:1]
  1545. }
  1546. for _, chname := range channels {
  1547. casefoldedChname, err := CasefoldChannel(chname)
  1548. channel := server.channels.Get(casefoldedChname)
  1549. if err != nil || channel == nil {
  1550. if len(chname) > 0 {
  1551. client.Send(nil, server.name, ERR_NOSUCHCHANNEL, client.nick, chname, "No such channel")
  1552. }
  1553. continue
  1554. }
  1555. channel.Names(client)
  1556. }
  1557. return false
  1558. }
  1559. // VERSION [<server>]
  1560. func versionHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
  1561. var target string
  1562. if len(msg.Params) > 0 {
  1563. target = msg.Params[0]
  1564. }
  1565. casefoldedTarget, err := Casefold(target)
  1566. if target != "" && (err != nil || casefoldedTarget != server.nameCasefolded) {
  1567. client.Send(nil, server.name, ERR_NOSUCHSERVER, client.nick, target, "No such server")
  1568. return false
  1569. }
  1570. client.Send(nil, server.name, RPL_VERSION, client.nick, Ver, server.name)
  1571. client.RplISupport()
  1572. return false
  1573. }
  1574. // INVITE <nickname> <channel>
  1575. func inviteHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
  1576. nickname := msg.Params[0]
  1577. channelName := msg.Params[1]
  1578. casefoldedNickname, err := CasefoldName(nickname)
  1579. target := server.clients.Get(casefoldedNickname)
  1580. if err != nil || target == nil {
  1581. client.Send(nil, server.name, ERR_NOSUCHNICK, client.nick, nickname, "No such nick")
  1582. return false
  1583. }
  1584. casefoldedChannelName, err := CasefoldChannel(channelName)
  1585. channel := server.channels.Get(casefoldedChannelName)
  1586. if err != nil || channel == nil {
  1587. client.Send(nil, server.name, RPL_INVITING, client.nick, target.nick, channelName)
  1588. target.Send(nil, client.nickMaskString, "INVITE", target.nick, channel.name)
  1589. return true
  1590. }
  1591. channel.Invite(target, client)
  1592. return false
  1593. }
  1594. // TIME [<server>]
  1595. func timeHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
  1596. var target string
  1597. if len(msg.Params) > 0 {
  1598. target = msg.Params[0]
  1599. }
  1600. casefoldedTarget, err := Casefold(target)
  1601. if (target != "") && err != nil || (casefoldedTarget != server.nameCasefolded) {
  1602. client.Send(nil, server.name, ERR_NOSUCHSERVER, client.nick, target, "No such server")
  1603. return false
  1604. }
  1605. client.Send(nil, server.name, RPL_TIME, client.nick, server.name, time.Now().Format(time.RFC1123))
  1606. return false
  1607. }
  1608. // KILL <nickname> <comment>
  1609. func killHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
  1610. nickname := msg.Params[0]
  1611. comment := "<no reason supplied>"
  1612. if len(msg.Params) > 1 {
  1613. comment = msg.Params[1]
  1614. }
  1615. casefoldedNickname, err := CasefoldName(nickname)
  1616. target := server.clients.Get(casefoldedNickname)
  1617. if err != nil || target == nil {
  1618. client.Send(nil, client.server.name, ERR_NOSUCHNICK, nickname, "No such nick")
  1619. return false
  1620. }
  1621. quitMsg := fmt.Sprintf("Killed (%s (%s))", client.nick, comment)
  1622. target.Quit(quitMsg)
  1623. target.destroy()
  1624. return false
  1625. }
  1626. // WHOWAS <nickname> [<count> [<server>]]
  1627. func whowasHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
  1628. nicknames := strings.Split(msg.Params[0], ",")
  1629. var count int64
  1630. if len(msg.Params) > 1 {
  1631. count, _ = strconv.ParseInt(msg.Params[1], 10, 64)
  1632. }
  1633. //var target string
  1634. //if len(msg.Params) > 2 {
  1635. // target = msg.Params[2]
  1636. //}
  1637. for _, nickname := range nicknames {
  1638. results := server.whoWas.Find(nickname, count)
  1639. if len(results) == 0 {
  1640. if len(nickname) > 0 {
  1641. client.Send(nil, server.name, ERR_WASNOSUCHNICK, client.nick, nickname, "There was no such nickname")
  1642. }
  1643. } else {
  1644. for _, whoWas := range results {
  1645. client.Send(nil, server.name, RPL_WHOWASUSER, client.nick, whoWas.nickname, whoWas.username, whoWas.hostname, "*", whoWas.realname)
  1646. }
  1647. }
  1648. if len(nickname) > 0 {
  1649. client.Send(nil, server.name, RPL_ENDOFWHOWAS, client.nick, nickname, "End of WHOWAS")
  1650. }
  1651. }
  1652. return false
  1653. }
  1654. // LUSERS [<mask> [<server>]]
  1655. func lusersHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
  1656. //TODO(vegax87) Fix network statistics and additional parameters
  1657. var totalcount, invisiblecount, opercount int
  1658. server.clients.ByNickMutex.RLock()
  1659. defer server.clients.ByNickMutex.RUnlock()
  1660. for _, onlineusers := range server.clients.ByNick {
  1661. totalcount++
  1662. if onlineusers.flags[Invisible] {
  1663. invisiblecount++
  1664. }
  1665. if onlineusers.flags[Operator] {
  1666. opercount++
  1667. }
  1668. }
  1669. 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))
  1670. client.Send(nil, server.name, RPL_LUSEROP, client.nick, fmt.Sprintf("%d IRC Operators online", opercount))
  1671. client.Send(nil, server.name, RPL_LUSERCHANNELS, client.nick, fmt.Sprintf("%d channels formed", len(server.channels)))
  1672. client.Send(nil, server.name, RPL_LUSERME, client.nick, fmt.Sprintf("I have %d clients and %d servers", totalcount, 1))
  1673. return false
  1674. }
  1675. // USERHOST <nickname> [<nickname> <nickname> ...]
  1676. func userhostHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
  1677. returnedNicks := make(map[string]bool)
  1678. for i, nickname := range msg.Params {
  1679. if i >= 10 {
  1680. break
  1681. }
  1682. casefoldedNickname, err := CasefoldName(nickname)
  1683. target := server.clients.Get(casefoldedNickname)
  1684. if err != nil || target == nil {
  1685. client.Send(nil, client.server.name, ERR_NOSUCHNICK, nickname, "No such nick")
  1686. return false
  1687. }
  1688. if returnedNicks[casefoldedNickname] {
  1689. continue
  1690. }
  1691. // to prevent returning multiple results for a single nick
  1692. returnedNicks[casefoldedNickname] = true
  1693. var isOper, isAway string
  1694. if target.flags[Operator] {
  1695. isOper = "*"
  1696. }
  1697. if target.flags[Away] {
  1698. isAway = "-"
  1699. } else {
  1700. isAway = "+"
  1701. }
  1702. 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))
  1703. }
  1704. return false
  1705. }