From b421971b61943e02adf236fbc656be56d7ad19e9 Mon Sep 17 00:00:00 2001 From: Jeremy Latt Date: Sat, 1 Mar 2014 15:02:24 -0800 Subject: [PATCH 1/5] move db init/open functions into a single file --- ergonomadic.go | 25 +------------------------ irc/database.go | 32 ++++++++++++++++++++++++++++++++ irc/server.go | 8 +------- 3 files changed, 34 insertions(+), 31 deletions(-) create mode 100644 irc/database.go diff --git a/ergonomadic.go b/ergonomadic.go index e04f9e8a..f47f695d 100644 --- a/ergonomadic.go +++ b/ergonomadic.go @@ -2,12 +2,10 @@ package main import ( "code.google.com/p/go.crypto/bcrypt" - "database/sql" "encoding/base64" "flag" "fmt" "github.com/jlatt/ergonomadic/irc" - _ "github.com/mattn/go-sqlite3" "log" "os" ) @@ -21,27 +19,6 @@ func genPasswd(passwd string) { fmt.Println(encoded) } -func initDB(config *irc.Config) { - os.Remove(config.Database()) - - db, err := sql.Open("sqlite3", config.Database()) - if err != nil { - log.Fatal(err) - } - defer db.Close() - - _, err = db.Exec(` - CREATE TABLE channel ( - name TEXT NOT NULL UNIQUE, - flags TEXT NOT NULL, - key TEXT NOT NULL, - topic TEXT NOT NULL, - user_limit INTEGER DEFAULT 0)`) - if err != nil { - log.Fatal(err) - } -} - func main() { conf := flag.String("conf", "ergonomadic.json", "ergonomadic config file") initdb := flag.Bool("initdb", false, "initialize database") @@ -59,7 +36,7 @@ func main() { } if *initdb { - initDB(config) + irc.InitDB(config.Database()) return } diff --git a/irc/database.go b/irc/database.go new file mode 100644 index 00000000..1ff3bd67 --- /dev/null +++ b/irc/database.go @@ -0,0 +1,32 @@ +package irc + +import ( + "database/sql" + _ "github.com/mattn/go-sqlite3" + "log" + "os" +) + +func InitDB(path string) { + os.Remove(path) + db := OpenDB(path) + defer db.Close() + _, err := db.Exec(` + CREATE TABLE channel ( + name TEXT NOT NULL UNIQUE, + flags TEXT NOT NULL, + key TEXT NOT NULL, + topic TEXT NOT NULL, + user_limit INTEGER DEFAULT 0)`) + if err != nil { + log.Fatal(err) + } +} + +func OpenDB(path string) *sql.DB { + db, err := sql.Open("sqlite3", path) + if err != nil { + log.Fatal(err) + } + return db +} diff --git a/irc/server.go b/irc/server.go index 49c5f4ad..3a4cf69b 100644 --- a/irc/server.go +++ b/irc/server.go @@ -7,7 +7,6 @@ import ( "database/sql" "encoding/binary" "fmt" - _ "github.com/mattn/go-sqlite3" "log" "net" "os" @@ -36,17 +35,12 @@ type Server struct { } func NewServer(config *Config) *Server { - db, err := sql.Open("sqlite3", config.Database()) - if err != nil { - log.Fatal(err) - } - server := &Server{ channels: make(ChannelNameMap), clients: make(ClientNameMap), commands: make(chan Command, 16), ctime: time.Now(), - db: db, + db: OpenDB(config.Database()), idle: make(chan *Client, 16), motdFile: config.MOTD, name: config.Name, From 9aa7debbfeae85d46f1e78d186f6d59a104aad52 Mon Sep 17 00:00:00 2001 From: Jeremy Latt Date: Sat, 1 Mar 2014 15:10:04 -0800 Subject: [PATCH 2/5] move password handling into a single file --- ergonomadic.go | 19 ++++++------------- irc/commands.go | 3 +-- irc/config.go | 6 +----- irc/password.go | 37 +++++++++++++++++++++++++++++++++++++ 4 files changed, 45 insertions(+), 20 deletions(-) create mode 100644 irc/password.go diff --git a/ergonomadic.go b/ergonomadic.go index f47f695d..663d1838 100644 --- a/ergonomadic.go +++ b/ergonomadic.go @@ -1,24 +1,12 @@ package main import ( - "code.google.com/p/go.crypto/bcrypt" - "encoding/base64" "flag" "fmt" "github.com/jlatt/ergonomadic/irc" "log" - "os" ) -func genPasswd(passwd string) { - crypted, err := bcrypt.GenerateFromPassword([]byte(passwd), bcrypt.MinCost) - if err != nil { - log.Fatal(err) - } - encoded := base64.StdEncoding.EncodeToString(crypted) - fmt.Println(encoded) -} - func main() { conf := flag.String("conf", "ergonomadic.json", "ergonomadic config file") initdb := flag.Bool("initdb", false, "initialize database") @@ -26,7 +14,11 @@ func main() { flag.Parse() if *passwd != "" { - genPasswd(*passwd) + encoded, err := irc.GenerateEncodedPassword(*passwd) + if err != nil { + log.Fatal(err) + } + fmt.Println(encoded) return } @@ -37,6 +29,7 @@ func main() { if *initdb { irc.InitDB(config.Database()) + log.Println("database initialized: " + config.Database()) return } diff --git a/irc/commands.go b/irc/commands.go index 8229d217..7f7a14bb 100644 --- a/irc/commands.go +++ b/irc/commands.go @@ -1,7 +1,6 @@ package irc import ( - "code.google.com/p/go.crypto/bcrypt" "code.google.com/p/go.text/unicode/norm" "errors" "fmt" @@ -214,7 +213,7 @@ func (cmd *PassCommand) CheckPassword() { if cmd.hash == nil { return } - cmd.err = bcrypt.CompareHashAndPassword(cmd.hash, cmd.password) + cmd.err = ComparePassword(cmd.hash, cmd.password) } func NewPassCommand(args []string) (editableCommand, error) { diff --git a/irc/config.go b/irc/config.go index 07518f00..9aabe12f 100644 --- a/irc/config.go +++ b/irc/config.go @@ -1,7 +1,6 @@ package irc import ( - "encoding/base64" "encoding/json" "log" "os" @@ -9,10 +8,7 @@ import ( ) func decodePassword(password string) []byte { - if password == "" { - return nil - } - bytes, err := base64.StdEncoding.DecodeString(password) + bytes, err := DecodePassword(password) if err != nil { log.Fatal(err) } diff --git a/irc/password.go b/irc/password.go new file mode 100644 index 00000000..1426c402 --- /dev/null +++ b/irc/password.go @@ -0,0 +1,37 @@ +package irc + +import ( + "code.google.com/p/go.crypto/bcrypt" + "encoding/base64" + "errors" +) + +var ( + EmptyPasswordError = errors.New("empty password") +) + +func GenerateEncodedPassword(passwd string) (encoded string, err error) { + if passwd == "" { + err = EmptyPasswordError + return + } + bcrypted, err := bcrypt.GenerateFromPassword([]byte(passwd), bcrypt.MinCost) + if err != nil { + return + } + encoded = base64.StdEncoding.EncodeToString(bcrypted) + return +} + +func DecodePassword(encoded string) (decoded []byte, err error) { + if encoded == "" { + err = EmptyPasswordError + return + } + decoded, err = base64.StdEncoding.DecodeString(encoded) + return +} + +func ComparePassword(hash, password []byte) error { + return bcrypt.CompareHashAndPassword(hash, password) +} From 857907320dcab2a14cc21f492b7e684ac208f391 Mon Sep 17 00:00:00 2001 From: Edmund Huber Date: Sun, 2 Mar 2014 19:56:21 +0100 Subject: [PATCH 3/5] allow underscores in nicks --- irc/constants.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/irc/constants.go b/irc/constants.go index 83e73efb..eed3d388 100644 --- a/irc/constants.go +++ b/irc/constants.go @@ -19,7 +19,7 @@ var ( // regexps ChannelNameExpr = regexp.MustCompile(`^[&!#+][\pL\pN]{1,63}$`) NicknameExpr = regexp.MustCompile( - "^[\\pL\\[\\]{}^`][\\pL\\pN\\[\\]{}^`]{1,31}$") + "^[\\pL\\[\\]{}^`_][\\pL\\pN\\[\\]{}^`_]{1,31}$") ) const ( From 8f0d2b89ee226533b19374599ecc1cbabee622d4 Mon Sep 17 00:00:00 2001 From: Jeremy Latt Date: Sun, 2 Mar 2014 11:06:02 -0800 Subject: [PATCH 4/5] v.1.2.12 --- irc/constants.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/irc/constants.go b/irc/constants.go index eed3d388..f68c0c9e 100644 --- a/irc/constants.go +++ b/irc/constants.go @@ -23,7 +23,7 @@ var ( ) const ( - SEM_VER = "ergonomadic-1.2.11" + SEM_VER = "ergonomadic-1.2.12" CRLF = "\r\n" MAX_REPLY_LEN = 512 - len(CRLF) From 6aa6f0aeaae8673f81eb14544fcad132a2811fd0 Mon Sep 17 00:00:00 2001 From: Jeremy Latt Date: Sun, 2 Mar 2014 11:36:00 -0800 Subject: [PATCH 5/5] notify clients when the server shuts down --- irc/server.go | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/irc/server.go b/irc/server.go index 49c5f4ad..896c4ac4 100644 --- a/irc/server.go +++ b/irc/server.go @@ -16,6 +16,7 @@ import ( "runtime/debug" "runtime/pprof" "strings" + "syscall" "time" ) @@ -57,7 +58,7 @@ func NewServer(config *Config) *Server { timeout: make(chan *Client, 16), } - signal.Notify(server.signals, os.Interrupt, os.Kill) + signal.Notify(server.signals, syscall.SIGINT, syscall.SIGHUP) server.loadChannels() @@ -138,14 +139,20 @@ func (server *Server) processCommand(cmd Command) { } } +func (server *Server) Shutdown() { + server.db.Close() + for _, client := range server.clients { + client.Reply(RplNotice(server, client, "shutting down")) + } +} + func (server *Server) Run() { done := false for !done { select { case <-server.signals: - server.db.Close() + server.Shutdown() done = true - continue case conn := <-server.newConns: NewClient(server, conn)