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

@ -238,34 +238,35 @@ func (self *boardModel) Update(db Database) {
} }
type post struct { type post struct {
_i18n *I18N _i18n *I18N
truncated bool truncated bool
prefix string prefix string
board string board string
PostName string PostName string
PostSubject string PostSubject string
PostMessage string PostMessage string
message_rendered string message_rendered string
Message_id string Message_id string
MessagePath string MessagePath string
addr string addr string
Newsgroup string Newsgroup string
op bool op bool
Posted int64 Posted int64
Parent string Parent string
sage bool sage bool
Key string Key string
Files []AttachmentModel Files []AttachmentModel
HashLong string HashLong string
HashShort string HashShort string
URL string URL string
Tripcode string Tripcode string
BodyMarkup string BodyMarkup string
PostMarkup string PostMarkup string
PostPrefix string PostPrefix string
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))
@ -559,7 +565,8 @@ func (self *post) Truncate() PostModel {
sage: self.sage, sage: self.sage,
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 {
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 { } 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 { } 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])