Sanitize names on join and /nick.
authorAndrey Petrov <andrey.petrov@shazow.net>
Tue, 20 Jan 2015 07:15:27 +0000 (23:15 -0800)
committerAndrey Petrov <andrey.petrov@shazow.net>
Tue, 20 Jan 2015 22:13:59 +0000 (14:13 -0800)
chat/command.go
chat/room.go
chat/sanitize.go [new file with mode: 0644]
host.go
identity.go

index fcd5d05ddaf19184e8220d3776bc041fdd267aa4..eb085c93766d23274dafbb1637a15315a88e5477 100644 (file)
@@ -151,8 +151,7 @@ func InitCommands(c *Commands) {
                        }
 
                        oldId := member.Id()
-                       member.SetId(args[0])
-
+                       member.SetId(SanitizeName(args[0]))
                        err := room.Rename(oldId, member)
                        if err != nil {
                                member.SetId(oldId)
index 041fe9e124497ab3a25349d34305d94dbedaf3a7..7d1b3af9592c1a7c2ae35574a59854922455c048 100644 (file)
@@ -14,6 +14,10 @@ const roomBuffer = 10
 // closed.
 var ErrRoomClosed = errors.New("room closed")
 
+// The error returned when a user attempts to join with an invalid name, such
+// as empty string.
+var ErrInvalidName = errors.New("invalid name")
+
 // Member is a User with per-Room metadata attached to it.
 type Member struct {
        *User
@@ -128,6 +132,9 @@ func (r *Room) Join(u *User) (*Member, error) {
        if r.closed {
                return nil, ErrRoomClosed
        }
+       if u.Id() == "" {
+               return nil, ErrInvalidName
+       }
        member := Member{u, false}
        err := r.members.Add(&member)
        if err != nil {
@@ -152,6 +159,9 @@ func (r *Room) Leave(u *User) error {
 
 // Rename member with a new identity. This will not call rename on the member.
 func (r *Room) Rename(oldId string, identity Identifier) error {
+       if identity.Id() == "" {
+               return ErrInvalidName
+       }
        err := r.members.Replace(oldId, identity)
        if err != nil {
                return err
diff --git a/chat/sanitize.go b/chat/sanitize.go
new file mode 100644 (file)
index 0000000..8b162cd
--- /dev/null
@@ -0,0 +1,17 @@
+package chat
+
+import "regexp"
+
+var reStripName = regexp.MustCompile("[^\\w.-]")
+
+// SanitizeName returns a name with only allowed characters.
+func SanitizeName(s string) string {
+       return reStripName.ReplaceAllString(s, "")
+}
+
+var reStripData = regexp.MustCompile("[^[:ascii:]]")
+
+// SanitizeData returns a string with only allowed characters for client-provided metadata inputs.
+func SanitizeData(s string) string {
+       return reStripData.ReplaceAllString(s, "")
+}
diff --git a/host.go b/host.go
index d099772732d088359a4fe8252706db9dd958c270..e8226f28f6c101751a009c83009be250e79e5b20 100644 (file)
--- a/host.go
+++ b/host.go
@@ -87,7 +87,7 @@ func (h *Host) Connect(term *sshd.Terminal) {
        }
 
        member, err := h.Join(user)
-       if err == chat.ErrIdTaken {
+       if err != nil {
                // Try again...
                id.SetName(fmt.Sprintf("Guest%d", h.count))
                member, err = h.Join(user)
index c41d382ccc406b58170d53e1112c1f2c96622a6f..bfd46fa07c466c35afdbb8e541d282bb3c085e96 100644 (file)
@@ -18,7 +18,7 @@ type Identity struct {
 func NewIdentity(conn sshd.Connection) *Identity {
        return &Identity{
                Connection: conn,
-               id:         conn.Name(),
+               id:         chat.SanitizeName(conn.Name()),
        }
 }