From a66d31f44757990d8290b16abad8b93bd61e1afc Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Tue, 4 Apr 2017 11:01:02 -0400 Subject: [PATCH] enforce limits better --- Makefile | 2 +- contrib/backends/srndv2/src/srnd/daemon.go | 2 +- .../backends/srndv2/src/srnd/frontend_http.go | 4 +- contrib/backends/srndv2/src/srnd/line.go | 17 +++++-- contrib/backends/srndv2/src/srnd/message.go | 50 +++++++++++++------ 5 files changed, 51 insertions(+), 24 deletions(-) diff --git a/Makefile b/Makefile index 9e33fc5..ced8091 100644 --- a/Makefile +++ b/Makefile @@ -8,7 +8,7 @@ VENDOR_JS=$(REPO)/contrib/js/vendor SRND_DIR=$(REPO)/contrib/backends/srndv2 SRND=$(REPO)/srndv2 -all: build +all: clean build build: js srnd diff --git a/contrib/backends/srndv2/src/srnd/daemon.go b/contrib/backends/srndv2/src/srnd/daemon.go index 4003776..3631838 100644 --- a/contrib/backends/srndv2/src/srnd/daemon.go +++ b/contrib/backends/srndv2/src/srnd/daemon.go @@ -596,7 +596,7 @@ func (self *NNTPDaemon) Run() { nntp.Pack() file := self.store.CreateFile(nntp.MessageID()) if file != nil { - err = nntp.WriteTo(file) + err = nntp.WriteTo(file, MaxMessageSize) file.Close() if err == nil { self.loadFromInfeed(nntp.MessageID()) diff --git a/contrib/backends/srndv2/src/srnd/frontend_http.go b/contrib/backends/srndv2/src/srnd/frontend_http.go index 6e5504b..17c4a3b 100644 --- a/contrib/backends/srndv2/src/srnd/frontend_http.go +++ b/contrib/backends/srndv2/src/srnd/frontend_http.go @@ -381,7 +381,7 @@ func (self *httpFrontend) poll() { f := self.daemon.store.CreateFile(nntp.MessageID()) if f != nil { b := new(bytes.Buffer) - err := nntp.WriteTo(b) + err := nntp.WriteTo(b, self.daemon.messageSizeLimitFor(nntp.Newsgroup())) if err == nil { r := bufio.NewReader(b) 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")) return } else { - err = nntp.WriteTo(f) + err = nntp.WriteTo(f, self.daemon.messageSizeLimitFor(nntp.Newsgroup())) f.Close() if err == nil { go self.daemon.loadFromInfeed(nntp.MessageID()) diff --git a/contrib/backends/srndv2/src/srnd/line.go b/contrib/backends/srndv2/src/srnd/line.go index ae2c479..16beec4 100644 --- a/contrib/backends/srndv2/src/srnd/line.go +++ b/contrib/backends/srndv2/src/srnd/line.go @@ -6,18 +6,25 @@ import ( ) 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{ - w: w, + w: w, + Left: limit, } } 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) - _, err = l.w.Write(data) + n, err = l.w.Write(data) + l.Left -= int64(n) + return } diff --git a/contrib/backends/srndv2/src/srnd/message.go b/contrib/backends/srndv2/src/srnd/message.go index 7005cba..a00c411 100644 --- a/contrib/backends/srndv2/src/srnd/message.go +++ b/contrib/backends/srndv2/src/srnd/message.go @@ -83,9 +83,9 @@ type NNTPMessage interface { // all headers Headers() ArticleHeaders // write out everything - WriteTo(wr io.Writer) error + WriteTo(wr io.Writer, limit int64) error // write out body - WriteBody(wr io.Writer) error + WriteBody(wr io.Writer, limit int64) error // attach a file Attach(att NNTPAttachment) // get the plaintext message if it exists @@ -175,7 +175,7 @@ func signArticle(nntp NNTPMessage, seed []byte) (signed *nntpArticle, err error) signed.signedPart = &nntpAttachment{} // write body to sign buffer mw := io.MultiWriter(sha, signed.signedPart) - err = nntp.WriteTo(mw) + err = nntp.WriteTo(mw, MaxMessageSize) mw.Write([]byte{10}) if err == nil { // build keypair @@ -198,15 +198,20 @@ func signArticle(nntp NNTPMessage, seed []byte) (signed *nntpArticle, err error) return } -func (self *nntpArticle) WriteTo(wr io.Writer) (err error) { +func (self *nntpArticle) WriteTo(wr io.Writer, limit int64) (err error) { // write headers + var n int hdrs := self.headers for hdr, hdr_vals := range hdrs { for _, hdr_val := range hdr_vals { - wr.Write([]byte(hdr)) - wr.Write([]byte(": ")) - wr.Write([]byte(hdr_val)) - _, err = wr.Write([]byte{10}) + n, err = wr.Write([]byte(hdr)) + limit -= int64(n) + n, err = wr.Write([]byte(": ")) + 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 { log.Println("error while writing headers", err) return @@ -214,14 +219,19 @@ func (self *nntpArticle) WriteTo(wr io.Writer) (err error) { } } // done headers - _, err = wr.Write([]byte{10}) + n, err = wr.Write([]byte{10}) + limit -= int64(n) if err != nil { log.Println("error while writing body", err) return } - // write body - err = self.WriteBody(wr) + if limit > 0 { + // write body + err = self.WriteBody(wr, limit) + } else { + err = ErrOversizedMessage + } return } @@ -359,10 +369,15 @@ func (self *nntpArticle) Attach(att NNTPAttachment) { 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 + var n int 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 } self.Pack() @@ -375,7 +390,8 @@ func (self *nntpArticle) WriteBody(wr io.Writer) (err error) { boundary, ok := params["boundary"] if ok { - w := multipart.NewWriter(NewLineWriter(wr)) + nlw := NewLineWriter(wr, limit) + w := multipart.NewWriter(nlw) err = w.SetBoundary(boundary) if err == nil { @@ -411,9 +427,13 @@ func (self *nntpArticle) WriteBody(wr io.Writer) (err error) { } err = w.Close() w = nil + if nlw.Left <= 0 { + err = ErrOversizedMessage + } } else { + nlw := NewLineWriter(wr, limit) // write out message - _, err = io.WriteString(wr, self.message) + _, err = io.WriteString(nlw, self.message) } return err }