diff options
Diffstat (limited to 'hid')
| -rw-r--r-- | hid/main.go | 60 | 
1 files changed, 36 insertions, 24 deletions
| diff --git a/hid/main.go b/hid/main.go index 2c34f08..5e99a85 100644 --- a/hid/main.go +++ b/hid/main.go @@ -421,7 +421,7 @@ func ircFnmatch(pattern string, s string) bool {  }  var reMsg = regexp.MustCompile( -	`^(?:@[^ ]* +)(?::([^! ]*)(?:!([^@]*)@([^ ]*))? +)?([^ ]+)(.*)?$`) +	`^(@[^ ]* +)?(?::([^! ]*)(?:!([^@]*)@([^ ]*))? +)?([^ ]+)(.*)?$`)  var reArgs = regexp.MustCompile(`:.*| [^: ][^ ]*`)  type message struct { @@ -514,7 +514,7 @@ var (  	// behaviour seems to be unstated in the documentation.  	reUsername = regexp.MustCompile(`^[^\0\r\n @]+$`) -	reChannelName = regexp.MustCompile(`^[^\0\7\r\n ,:]+$`) +	reChannelName = regexp.MustCompile(`^[^\0\007\r\n ,:]+$`)  	reKey         = regexp.MustCompile(`^[^\r\n\f\t\v ]{1,23}$`)  	reUserMask    = regexp.MustCompile(`^[^!@]+![^!@]+@[^@!]+$`)  	reFingerprint = regexp.MustCompile(`^[a-fA-F0-9]{64}$`) @@ -754,17 +754,16 @@ type writeEvent struct {  var (  	started time.Time // when has the server been started -	users    map[string]*client  // maps nicknames to clients -	channels map[string]*channel // maps channel names to data +	users    = make(map[string]*client)     // maps nicknames to clients +	channels = make(map[string]*channel)    // maps channel names to data +	whowas   = make(map[string]*whowasInfo) // WHOWAS registry -	whowas map[string]*whowasInfo // WHOWAS registry - -	config         simpleConfig    // server configuration -	serverName     string          // our server name -	pingInterval   uint            // ping interval in seconds -	maxConnections int             // max connections allowed or 0 -	motd           []string        // MOTD (none if empty) -	operators      map[string]bool // TLS certificate fingerprints for IRCops +	config         simpleConfig            // server configuration +	serverName     string                  // our server name +	pingInterval   uint                    // ping interval in seconds +	maxConnections int                     // max connections allowed or 0 +	motd           []string                // MOTD (none if empty) +	operators      = make(map[string]bool) // TLS cert. fingerprints for IRCops  )  var ( @@ -814,8 +813,9 @@ func initiateQuit() {  func ircChannelCreate(name string) *channel {  	ch := &channel{  		name:      name, -		created:   time.Now(),  		userLimit: -1, +		created:   time.Now(), +		userModes: make(map[*client]uint),  	}  	channels[ircToCanon(name)] = ch  	return ch @@ -1046,10 +1046,15 @@ func (c *client) sendReplyVector(id int, items []string, args ...interface{}) {  	// We always send at least one message (there might be a client that  	// expects us to send this message at least once). +	if len(items) == 0 { +		items = append(items, "") +	} +  	for len(items) > 0 {  		// If not even a single item fits in the limit (which may happen,  		// in theory) it just gets cropped. We could also skip it.  		reply := append([]byte(common), items[0]...) +		items = items[1:]  		// Append as many items as fits in a single message.  		for len(items) > 0 && @@ -1120,10 +1125,10 @@ func isThisMe(target string) bool {  }  func (c *client) sendISUPPORT() { -	// Only # channels, +e supported, +I supported, unlimited arguments to MODE -	c.sendReply(RPL_ISUPPORT, "CHANTYPES=# EXCEPTS INVEX MODES"+ +	// Only # channels, +e supported, +I supported, unlimited arguments to MODE. +	c.sendReply(RPL_ISUPPORT, fmt.Sprintf("CHANTYPES=# EXCEPTS INVEX MODES"+  		" TARGMAX=WHOIS:,LIST:,NAMES:,PRIVMSG:1,NOTICE:1,KICK:"+ -		" NICKLEN=%d CHANNELLEN=%d", ircMaxNickname, ircMaxChannelName) +		" NICKLEN=%d CHANNELLEN=%d", ircMaxNickname, ircMaxChannelName))  }  func (c *client) tryFinishRegistration() { @@ -2170,8 +2175,7 @@ func ircSendWHOISReply(c, target *client) {  	nick := target.nickname  	c.sendReply(RPL_WHOISUSER, nick,  		target.username, target.hostname, target.realname) -	c.sendReply(RPL_WHOISSERVER, nick, -		serverName, "TODO server_info from configuration") +	c.sendReply(RPL_WHOISSERVER, nick, serverName, config["server_info"])  	if 0 != target.mode&ircUserModeOperator {  		c.sendReply(RPL_WHOISOPERATOR, nick)  	} @@ -2257,7 +2261,7 @@ func ircHandleWHOWAS(msg *message, c *client) {  			c.sendReply(RPL_WHOWASUSER, nick,  				info.username, info.hostname, info.realname)  			c.sendReply(RPL_WHOISSERVER, nick, -				serverName, "TODO server_info from configuration") +				serverName, config["server_info"])  		}  		c.sendReply(RPL_ENDOFWHOWAS, nick)  	} @@ -2689,7 +2693,7 @@ func ircHandleLINKS(msg *message, c *client) {  	if ircFnmatch(mask, serverName) {  		c.sendReply(RPL_LINKS, mask, serverName, -			0 /* hop count */, "TODO server_info from configuration") +			0 /* hop count */, config["server_info"])  	}  	c.sendReply(RPL_ENDOFLINKS, mask)  } @@ -2799,11 +2803,16 @@ func ircProcessMessage(c *client, msg *message, raw string) {  // Handle the results from initializing the client's connection.  func (c *client) onPrepared(host string, isTLS bool) { -	if isTLS { +	if !isTLS { +		c.conn = c.transport.(connCloseWrite) +	} else if tlsConf != nil {  		c.tls = tls.Server(c.transport, tlsConf)  		c.conn = c.tls  	} else { -		c.conn = c.transport.(connCloseWrite) +		log.Printf("could not initialize TLS for %s: TLS support disabled\n", +			c.address) +		c.kill("TLS support disabled") +		return  	}  	c.hostname = host @@ -2949,7 +2958,7 @@ func prepare(client *client) {  		// This is just for the TLS detection and doesn't need to be fatal.  		log.Println(err)  	} else { -		isTLS = tlsConf != nil && detectTLS(sysconn) +		isTLS = detectTLS(sysconn)  	}  	// FIXME: When the client sends no data, we still initialize its conn. @@ -2993,7 +3002,7 @@ func processOneEvent() {  		forceQuit("timeout")  	case conn := <-conns: -		if len(clients) >= maxConnections { +		if maxConnections > 0 && len(clients) >= maxConnections {  			log.Println("connection limit reached, refusing connection")  			conn.Close()  			break @@ -3014,6 +3023,8 @@ func processOneEvent() {  			hostname:   host,  			port:       port,  			capVersion: 301, +			opened:     time.Now(), +			lastActive: time.Now(),  			// TODO: Make this configurable and more fine-grained.  			antiflood: newFloodDetector(10*time.Second, 20),  		} @@ -3223,6 +3234,7 @@ func main() {  	}  	config = make(simpleConfig) +	config.loadDefaults(configTable)  	if err := config.updateFromFile(); err != nil && !os.IsNotExist(err) {  		log.Println("error loading configuration", err)  		os.Exit(1) | 
