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

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