Archived
1
0

add frontend key based blocking (initial)

This commit is contained in:
Jeff Becker 2018-03-09 16:16:41 -05:00
parent a0ff118323
commit 69f868ecb9
No known key found for this signature in database
GPG Key ID: F357B3B42F6F9B05
8 changed files with 107 additions and 45 deletions

View File

@ -8,6 +8,7 @@ import (
"bufio" "bufio"
"bytes" "bytes"
"encoding/base32" "encoding/base32"
"encoding/hex"
"fmt" "fmt"
"github.com/majestrate/configparser" "github.com/majestrate/configparser"
"io/ioutil" "io/ioutil"
@ -187,6 +188,7 @@ func GenSRNdConfig() *configparser.Configuration {
sect.Add("archive", "0") sect.Add("archive", "0")
sect.Add("article_lifetime", "0") sect.Add("article_lifetime", "0")
sect.Add("filters_file", "filters.txt") sect.Add("filters_file", "filters.txt")
sect.Add("secretkey", hex.EncodeToString(randbytes(32)))
// spamd settings // spamd settings
sect = conf.NewSection("spamd") sect = conf.NewSection("spamd")

View File

@ -305,10 +305,12 @@ type Database interface {
GetMessageIDByEncryptedIP(encaddr string) ([]string, error) GetMessageIDByEncryptedIP(encaddr string) ([]string, error)
// check if this public key is banned from posting // check if this public key is banned from posting
PubkeyIsBanned(pubkey string) (bool, error) PubkeyRejected(pubkey string) (bool, error)
// ban a public key from posting // ban a public key from posting
BanPubkey(pubkey string) error BlacklistPubkey(pubkey string) error
WhitelistPubkey(pubkey string) error
DeletePubkey(pubkey string) error
// get all message-id posted before a time // get all message-id posted before a time
GetPostsBefore(t time.Time) ([]string, error) GetPostsBefore(t time.Time) ([]string, error)

View File

@ -89,6 +89,7 @@ type NNTPMessage interface {
OP() bool OP() bool
// all attachments // all attachments
Attachments() []NNTPAttachment Attachments() []NNTPAttachment
FrontendPubkey() string
// all headers // all headers
Headers() ArticleHeaders Headers() ArticleHeaders
MIMEHeader() textproto.MIMEHeader MIMEHeader() textproto.MIMEHeader
@ -112,6 +113,10 @@ type NNTPMessage interface {
BodyReader() io.Reader BodyReader() io.Reader
} }
func (self *nntpArticle) FrontendPubkey() string {
return self.headers.Get("X-Frontend-Pubkey", "")
}
type nntpArticle struct { type nntpArticle struct {
// mime header // mime header
headers ArticleHeaders headers ArticleHeaders

View File

@ -45,7 +45,7 @@ type PostModel interface {
BaseModel BaseModel
CSSClass() string CSSClass() string
FrontendPubkey() string
MessageID() string MessageID() string
PostHash() string PostHash() string
ShortHash() string ShortHash() string

View File

@ -266,6 +266,7 @@ type post struct {
index int index int
Type string Type string
nntp_id int nntp_id int
FrontendPublicKey string
} }
func (self *post) NNTPID() int { func (self *post) NNTPID() int {
@ -378,6 +379,7 @@ func PostModelFromMessage(parent, prefix string, nntp NNTPMessage) PostModel {
p.addr = nntp.Addr() p.addr = nntp.Addr()
p.sage = nntp.Sage() p.sage = nntp.Sage()
p.Key = nntp.Pubkey() p.Key = nntp.Pubkey()
p.FrontendPublicKey = nntp.FrontendPubkey()
for _, att := range nntp.Attachments() { for _, att := range nntp.Attachments() {
p.Files = append(p.Files, att.ToModel(prefix)) p.Files = append(p.Files, att.ToModel(prefix))
} }
@ -411,6 +413,10 @@ func (self *post) PubkeyHex() string {
return self.Key return self.Key
} }
func (self *post) FrontendPubkey() string {
return self.FrontendPublicKey
}
func (self *post) Pubkey() string { func (self *post) Pubkey() string {
if len(self.Key) > 0 { if len(self.Key) > 0 {
return fmt.Sprintf("<label title=\"%s\">%s</label>", self.Key, makeTripcode(self.Key)) return fmt.Sprintf("<label title=\"%s\">%s</label>", self.Key, makeTripcode(self.Key))
@ -560,6 +566,7 @@ func (self *post) Truncate() PostModel {
Key: self.Key, Key: self.Key,
// TODO: copy? // TODO: copy?
Files: self.Files, Files: self.Files,
FrontendPublicKey: self.FrontendPublicKey,
} }
} }

View File

@ -422,7 +422,7 @@ func (self *nntpConnection) checkMIMEHeaderNoAuth(daemon *NNTPDaemon, hdr textpr
} }
if serverPubkeyIsValid(server_pubkey) { if serverPubkeyIsValid(server_pubkey) {
b, _ := daemon.database.PubkeyIsBanned(server_pubkey) b, _ := daemon.database.PubkeyRejected(server_pubkey)
if b { if b {
reason = "server's pubkey is banned" reason = "server's pubkey is banned"
ban = true ban = true
@ -448,7 +448,7 @@ func (self *nntpConnection) checkMIMEHeaderNoAuth(daemon *NNTPDaemon, hdr textpr
reason = "newsgroup banned" reason = "newsgroup banned"
ban = true ban = true
return return
} else if banned, _ = daemon.database.PubkeyIsBanned(pubkey); banned { } else if banned, _ = daemon.database.PubkeyRejected(pubkey); banned {
// check for banned pubkey // check for banned pubkey
reason = "poster's pubkey is banned" reason = "poster's pubkey is banned"
ban = true ban = true

View File

@ -186,7 +186,7 @@ func (self *PostgresDatabase) prepareStatements() {
GetPostAttachmentModels: "SELECT filepath, filename FROM ArticleAttachments WHERE message_id = $1", GetPostAttachmentModels: "SELECT filepath, filename FROM ArticleAttachments WHERE message_id = $1",
RegisterArticle_1: "INSERT INTO Articles (message_id, message_id_hash, message_newsgroup, time_obtained, message_ref_id) VALUES($1, $2, $3, $4, $5)", RegisterArticle_1: "INSERT INTO Articles (message_id, message_id_hash, message_newsgroup, time_obtained, message_ref_id) VALUES($1, $2, $3, $4, $5)",
RegisterArticle_2: "UPDATE Newsgroups SET last_post = $1 WHERE name = $2", RegisterArticle_2: "UPDATE Newsgroups SET last_post = $1 WHERE name = $2",
RegisterArticle_3: "INSERT INTO ArticlePosts(newsgroup, message_id, ref_id, name, subject, path, time_posted, message, addr) VALUES($1, $2, $3, $4, $5, $6, $7, $8, $9)", RegisterArticle_3: "INSERT INTO ArticlePosts(newsgroup, message_id, ref_id, name, subject, path, time_posted, message, addr, frontendpubkey) VALUES($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)",
RegisterArticle_4: "INSERT INTO ArticleThreads(root_message_id, last_bump, last_post, newsgroup) VALUES($1, $2, $2, $3)", RegisterArticle_4: "INSERT INTO ArticleThreads(root_message_id, last_bump, last_post, newsgroup) VALUES($1, $2, $2, $3)",
RegisterArticle_5: "SELECT COUNT(*) FROM ArticlePosts WHERE ref_id = $1", RegisterArticle_5: "SELECT COUNT(*) FROM ArticlePosts WHERE ref_id = $1",
RegisterArticle_6: "UPDATE ArticleThreads SET last_bump = $2 WHERE root_message_id = $1", RegisterArticle_6: "UPDATE ArticleThreads SET last_bump = $2 WHERE root_message_id = $1",
@ -257,6 +257,8 @@ func (self *PostgresDatabase) CreateTables() {
} else if version == 7 { } else if version == 7 {
self.upgrade7to8() self.upgrade7to8()
} else if version == 8 { } else if version == 8 {
self.upgrade8to9()
} else if version == 9 {
// we are up to date // we are up to date
log.Println("we are up to date at version", version) log.Println("we are up to date at version", version)
break break
@ -617,6 +619,18 @@ func (self *PostgresDatabase) upgrade7to8() {
self.setDBVersion(8) self.setDBVersion(8)
} }
func (self *PostgresDatabase) upgrade8to9() {
_, err := self.conn.Exec("ALTER TABLE ArticlePosts ADD COLUMN IF NOT EXISTS frontendpubkey TEXT NOT NULL DEFAULT ''")
if err != nil {
log.Fatalf(err.Error())
}
_, err = self.conn.Exec("CREATE TABLE IF NOT EXISTS nntpchan_pubkeys(status VARCHAR(16) NOT NULL, pubkey VARCHAR(64) PRIMARY KEY)")
if err != nil {
log.Fatalf(err.Error())
}
self.setDBVersion(9)
}
// create all tables for database version 0 // create all tables for database version 0
func (self *PostgresDatabase) createTablesV0() { func (self *PostgresDatabase) createTablesV0() {
tables := make(map[string]string) tables := make(map[string]string)
@ -1474,7 +1488,7 @@ func (self *PostgresDatabase) RegisterArticle(message NNTPMessage) (err error) {
return return
} }
// insert article post // insert article post
_, err = self.conn.Exec(self.stmt[RegisterArticle_3], group, msgid, message.Reference(), message.Name(), message.Subject(), message.Path(), message.Posted(), message.Message(), message.Addr()) _, err = self.conn.Exec(self.stmt[RegisterArticle_3], group, msgid, message.Reference(), message.Name(), message.Subject(), message.Path(), message.Posted(), message.Message(), message.Addr(), message.FrontendPubkey())
if err != nil { if err != nil {
log.Println("cannot insert article post", err) log.Println("cannot insert article post", err)
return return
@ -1877,7 +1891,6 @@ func (self *PostgresDatabase) GetMessageIDByEncryptedIP(encaddr string) (msgids
if err == nil { if err == nil {
msgids = append(msgids, msgid) msgids = append(msgids, msgid)
} }
} }
if rows != nil { if rows != nil {
rows.Close() rows.Close()
@ -1885,15 +1898,32 @@ func (self *PostgresDatabase) GetMessageIDByEncryptedIP(encaddr string) (msgids
return return
} }
func (self *PostgresDatabase) BanPubkey(pubkey string) (err error) { func (self *PostgresDatabase) WhitelistPubkey(pubkey string) (err error) {
// TODO: implement _, err = self.conn.Exec("INSERT INTO nntpchan_pubkeys VALUES ('whitelist', $1)", pubkey)
err = errors.New("ban pubkey not implemented")
return return
} }
func (self *PostgresDatabase) PubkeyIsBanned(pubkey string) (bool, error) { func (self *PostgresDatabase) DeletePubkey(pubkey string) (err error) {
// TODO: implement _, err = self.conn.Exec("DELETE FROM nntpchan_pubkeys WHERE pubkey = $1", pubkey)
return false, nil return
}
func (self *PostgresDatabase) BlacklistPubkey(pubkey string) (err error) {
_, err = self.conn.Exec("INSERT INTO nntpchan_pubkeys VALUES ('blacklist', $1)", pubkey)
return
}
// return true if we should drop this message with this frontend pubkey
func (self *PostgresDatabase) PubkeyRejected(pubkey string) (bool, error) {
var num int64
var drop bool
var err error
err = self.conn.QueryRow("SELECT COUNT(pubkey) FROM nntpchan_pubkeys WHERE pubkey = $1 AND status = 'whitelist'", pubkey).Scan(&num)
if err == nil && num == 0 {
err = self.conn.QueryRow("SELECT COUNT(pubkey) FROM nntpchan_pubkeys WHERE pubkey = $1 and status = 'blacklist'", pubkey).Scan(&num)
drop = num > 0
}
return drop, err
} }
func (self *PostgresDatabase) GetPostsBefore(t time.Time) (msgids []string, err error) { func (self *PostgresDatabase) GetPostsBefore(t time.Time) (msgids []string, err error) {

View File

@ -128,11 +128,27 @@ func main() {
} else { } else {
fmt.Fprintf(os.Stdout, "Usage: %s tool nntp add-login username password\n", os.Args[0]) fmt.Fprintf(os.Stdout, "Usage: %s tool nntp add-login username password\n", os.Args[0])
} }
} else if action == "whitelist" {
daemon.Setup()
err := daemon.GetDatabase().WhitelistPubkey(os.Args[4])
if err == nil {
fmt.Println("OK")
} else { } else {
fmt.Fprintf(os.Stdout, "Usage: %s tool nntp [add-login|del-login]\n", os.Args[0]) fmt.Println(err)
}
} else if action == "blacklist" {
daemon.Setup()
err := daemon.GetDatabase().BlacklistPubkey(os.Args[4])
if err == nil {
fmt.Println("OK")
} else {
fmt.Println(err)
} }
} else { } else {
fmt.Fprintf(os.Stdout, "Usage: %s tool nntp [add-login|del-login]\n", os.Args[0]) fmt.Fprintf(os.Stdout, "Usage: %s tool nntp [add-login|del-login|whitelist|blacklist]\n", os.Args[0])
}
} else {
fmt.Fprintf(os.Stdout, "Usage: %s tool nntp [add-login|del-login|whitelist|blacklist]\n", os.Args[0])
} }
} else { } else {
fmt.Fprintf(os.Stdout, "Usage: %s tool [rethumb|keygen|nntp|mod|expire]\n", os.Args[0]) fmt.Fprintf(os.Stdout, "Usage: %s tool [rethumb|keygen|nntp|mod|expire]\n", os.Args[0])