Archived
1
0

enforce limits better

This commit is contained in:
Jeff Becker 2017-04-04 11:01:02 -04:00
parent f482c8972e
commit a66d31f447
5 changed files with 51 additions and 24 deletions

View File

@ -8,7 +8,7 @@ VENDOR_JS=$(REPO)/contrib/js/vendor
SRND_DIR=$(REPO)/contrib/backends/srndv2 SRND_DIR=$(REPO)/contrib/backends/srndv2
SRND=$(REPO)/srndv2 SRND=$(REPO)/srndv2
all: build all: clean build
build: js srnd build: js srnd

View File

@ -596,7 +596,7 @@ func (self *NNTPDaemon) Run() {
nntp.Pack() nntp.Pack()
file := self.store.CreateFile(nntp.MessageID()) file := self.store.CreateFile(nntp.MessageID())
if file != nil { if file != nil {
err = nntp.WriteTo(file) err = nntp.WriteTo(file, MaxMessageSize)
file.Close() file.Close()
if err == nil { if err == nil {
self.loadFromInfeed(nntp.MessageID()) self.loadFromInfeed(nntp.MessageID())

View File

@ -381,7 +381,7 @@ func (self *httpFrontend) poll() {
f := self.daemon.store.CreateFile(nntp.MessageID()) f := self.daemon.store.CreateFile(nntp.MessageID())
if f != nil { if f != nil {
b := new(bytes.Buffer) b := new(bytes.Buffer)
err := nntp.WriteTo(b) err := nntp.WriteTo(b, self.daemon.messageSizeLimitFor(nntp.Newsgroup()))
if err == nil { if err == nil {
r := bufio.NewReader(b) r := bufio.NewReader(b)
var msg *mail.Message var msg *mail.Message
@ -955,7 +955,7 @@ func (self *httpFrontend) handle_postRequest(pr *postRequest, b bannedFunc, e er
e(errors.New("failed to store article")) e(errors.New("failed to store article"))
return return
} else { } else {
err = nntp.WriteTo(f) err = nntp.WriteTo(f, self.daemon.messageSizeLimitFor(nntp.Newsgroup()))
f.Close() f.Close()
if err == nil { if err == nil {
go self.daemon.loadFromInfeed(nntp.MessageID()) go self.daemon.loadFromInfeed(nntp.MessageID())

View File

@ -7,17 +7,24 @@ import (
type LineWriter struct { type LineWriter struct {
w io.Writer w io.Writer
Left int64
} }
func NewLineWriter(w io.Writer) *LineWriter { func NewLineWriter(w io.Writer, limit int64) *LineWriter {
return &LineWriter{ return &LineWriter{
w: w, w: w,
Left: limit,
} }
} }
func (l *LineWriter) Write(data []byte) (n int, err error) { func (l *LineWriter) Write(data []byte) (n int, err error) {
n = len(data) if l.Left <= 0 {
err = ErrOversizedMessage
return
}
data = bytes.Replace(data, []byte{13, 10}, []byte{10}, -1) data = bytes.Replace(data, []byte{13, 10}, []byte{10}, -1)
_, err = l.w.Write(data) n, err = l.w.Write(data)
l.Left -= int64(n)
return return
} }

View File

@ -83,9 +83,9 @@ type NNTPMessage interface {
// all headers // all headers
Headers() ArticleHeaders Headers() ArticleHeaders
// write out everything // write out everything
WriteTo(wr io.Writer) error WriteTo(wr io.Writer, limit int64) error
// write out body // write out body
WriteBody(wr io.Writer) error WriteBody(wr io.Writer, limit int64) error
// attach a file // attach a file
Attach(att NNTPAttachment) Attach(att NNTPAttachment)
// get the plaintext message if it exists // get the plaintext message if it exists
@ -175,7 +175,7 @@ func signArticle(nntp NNTPMessage, seed []byte) (signed *nntpArticle, err error)
signed.signedPart = &nntpAttachment{} signed.signedPart = &nntpAttachment{}
// write body to sign buffer // write body to sign buffer
mw := io.MultiWriter(sha, signed.signedPart) mw := io.MultiWriter(sha, signed.signedPart)
err = nntp.WriteTo(mw) err = nntp.WriteTo(mw, MaxMessageSize)
mw.Write([]byte{10}) mw.Write([]byte{10})
if err == nil { if err == nil {
// build keypair // build keypair
@ -198,15 +198,20 @@ func signArticle(nntp NNTPMessage, seed []byte) (signed *nntpArticle, err error)
return return
} }
func (self *nntpArticle) WriteTo(wr io.Writer) (err error) { func (self *nntpArticle) WriteTo(wr io.Writer, limit int64) (err error) {
// write headers // write headers
var n int
hdrs := self.headers hdrs := self.headers
for hdr, hdr_vals := range hdrs { for hdr, hdr_vals := range hdrs {
for _, hdr_val := range hdr_vals { for _, hdr_val := range hdr_vals {
wr.Write([]byte(hdr)) n, err = wr.Write([]byte(hdr))
wr.Write([]byte(": ")) limit -= int64(n)
wr.Write([]byte(hdr_val)) n, err = wr.Write([]byte(": "))
_, err = wr.Write([]byte{10}) limit -= int64(n)
n, err = wr.Write([]byte(hdr_val))
limit -= int64(n)
n, err = wr.Write([]byte{10})
limit -= int64(n)
if err != nil { if err != nil {
log.Println("error while writing headers", err) log.Println("error while writing headers", err)
return return
@ -214,14 +219,19 @@ func (self *nntpArticle) WriteTo(wr io.Writer) (err error) {
} }
} }
// done headers // done headers
_, err = wr.Write([]byte{10}) n, err = wr.Write([]byte{10})
limit -= int64(n)
if err != nil { if err != nil {
log.Println("error while writing body", err) log.Println("error while writing body", err)
return return
} }
if limit > 0 {
// write body // write body
err = self.WriteBody(wr) err = self.WriteBody(wr, limit)
} else {
err = ErrOversizedMessage
}
return return
} }
@ -359,10 +369,15 @@ func (self *nntpArticle) Attach(att NNTPAttachment) {
self.attachments = append(self.attachments, att) self.attachments = append(self.attachments, att)
} }
func (self *nntpArticle) WriteBody(wr io.Writer) (err error) { func (self *nntpArticle) WriteBody(wr io.Writer, limit int64) (err error) {
// this is a signed message, don't treat it special // this is a signed message, don't treat it special
var n int
if self.signedPart != nil { if self.signedPart != nil {
_, err = wr.Write(self.signedPart.Bytes()) n, err = wr.Write(self.signedPart.Bytes())
limit -= int64(n)
if limit <= 0 {
err = ErrOversizedMessage
}
return return
} }
self.Pack() self.Pack()
@ -375,7 +390,8 @@ func (self *nntpArticle) WriteBody(wr io.Writer) (err error) {
boundary, ok := params["boundary"] boundary, ok := params["boundary"]
if ok { if ok {
w := multipart.NewWriter(NewLineWriter(wr)) nlw := NewLineWriter(wr, limit)
w := multipart.NewWriter(nlw)
err = w.SetBoundary(boundary) err = w.SetBoundary(boundary)
if err == nil { if err == nil {
@ -411,9 +427,13 @@ func (self *nntpArticle) WriteBody(wr io.Writer) (err error) {
} }
err = w.Close() err = w.Close()
w = nil w = nil
if nlw.Left <= 0 {
err = ErrOversizedMessage
}
} else { } else {
nlw := NewLineWriter(wr, limit)
// write out message // write out message
_, err = io.WriteString(wr, self.message) _, err = io.WriteString(nlw, self.message)
} }
return err return err
} }