add frontend key based blocking (initial)
This commit is contained in:
parent
a0ff118323
commit
69f868ecb9
@ -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")
|
||||||
|
@ -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)
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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) {
|
||||||
|
@ -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])
|
||||||
|
Reference in New Issue
Block a user