This commit is contained in:
2017-05-29 22:42:26 -04:00
parent 29de09712f
commit 481ce53fe4
9 changed files with 37 additions and 776 deletions

View File

@ -1,27 +0,0 @@
package common
import (
"bytes"
"encoding/base64"
)
// TODO: depend on go-i2p/common
const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-~"
// I2PEncoding returns an I2P compatible base64 encoding based on a custom alphabet
var I2PEncoding *base64.Encoding = base64.NewEncoding(alphabet)
// newlineDelimiter returns data for a scanner delimited by \n\n
func NewlineDelimiter(data []byte, atEOF bool) (advance int, token []byte, err error) {
if atEOF && len(data) == 0 {
return 0, nil, nil
}
if i := bytes.Index(data, []byte{'\n', '\n'}); i >= 0 {
return i + 2, data[0:i], nil
}
if atEOF {
return len(data), data, nil
}
return 0, nil, nil
}

View File

@ -1,40 +0,0 @@
package common
import (
"archive/zip"
"bytes"
log "github.com/Sirupsen/logrus"
)
func ParseZipReader(content []byte, size int) {
zr, err := zip.NewReader(bytes.NewReader(content), int64(size))
if err != nil {
panic("error")
}
var page, attatchment int
for _, file := range zr.File {
fileReader, err := file.Open()
buf := new(bytes.Buffer)
buf.ReadFrom(fileReader)
newStr := buf.String()
if err != nil {
log.Fatalf("Error opening enclosed zip file %s", err)
}
defer fileReader.Close()
switch file.Name[:4] {
case "atta":
log.Printf("Attatchment num %d: %s", attatchment, newStr)
attatchment++
case "page":
log.Printf("Page num %d: %s", page, newStr)
page++
case "avat":
log.Printf("avatar32.png: %s", newStr)
case "refe":
log.Printf("references.cfg: %s", newStr)
case "head":
log.Printf("Headers.dat: %s", newStr)
}
}
}

View File

@ -1,197 +0,0 @@
package enclosure
import (
"bufio"
"bytes"
"os"
"strconv"
"strings"
"github.com/kpetku/go-syndie/lib/common"
"github.com/kpetku/go-syndie/lib/syndieuri"
log "github.com/Sirupsen/logrus"
)
// Enclosure holds the reference to a Syndie Header and Message
type Enclosure struct {
Header *SyndieHeader
Message *SyndieTrailer
AuthenticationSig string
AuthorizationSig string
HmacPos int
}
// OpenFile opens a file and returns a populated Enclosure
func (enclosure *Enclosure) OpenFile(s string) *Enclosure {
var rest2 []byte
file, err := os.Open(s)
if err != nil {
log.WithFields(log.Fields{
"at": "(main)",
"file": s,
"reason": "failed to open file",
}).Fatalf("%s", err)
}
defer file.Close()
stat, err := file.Stat()
if err != nil {
log.WithFields(log.Fields{
"at": "(main)",
"file": s,
"reason": "failed stat file",
}).Fatalf("%s", err)
}
length := int(stat.Size())
log.Printf("File size is %d", length)
buf := make([]byte, 0, length)
scanner := bufio.NewScanner(file)
scanner.Buffer(buf, length)
scanner.Split(common.NewlineDelimiter)
for scanner.Scan() {
bs := scanner.Bytes()
if bytes.HasPrefix(bs, []byte("Syndie.Message.1.0")) {
str := strings.SplitAfter(string(bs), "\n")
enclosure.Header.Version = str[0]
for _, h := range str {
switch strings.Split(h, "=")[0] {
case "Author":
enclosure.Header.Author = strings.Split(h, "Author=")[1]
case "AuthenticationMask":
enclosure.Header.AuthenticationMask = strings.Split(h, "AuthenticationMask=")[1]
case "TargetChannel":
enclosure.Header.TargetChannel = strings.Split(h, "TargetChannel=")[1]
case "PostURI":
u := syndieuri.URI{}
u.Marshall(strings.Split(h, "PostURI=")[1])
enclosure.Header.PostURI = u
case "References":
var out []syndieuri.URI
r := strings.Split(h, "References=")[1:]
for _, ref := range r {
u := syndieuri.URI{}
u.Marshall(ref)
out = append(out, u)
}
enclosure.Header.References = out
case "Tags":
enclosure.Header.Tags = strings.Split(h, "Tags=")[1:]
case "OverwriteURI":
u := syndieuri.URI{}
u.Marshall(strings.Split(h, "OverwriteURI=")[1])
enclosure.Header.OverwriteURI = u
case "ForceNewThread":
if strings.Contains(strings.Split(h, "ForceNewThread=")[1], "true") {
enclosure.Header.ForceNewThread = true
}
case "RefuseReplies":
if strings.Contains(strings.Split(h, "RefuseReplies=")[1], "true") {
enclosure.Header.RefuseReplies = true
}
case "Cancel":
var out []syndieuri.URI
r := strings.Split(h, "Cancel=")[1:]
for _, canc := range r {
u := syndieuri.URI{}
u.Marshall(canc)
out = append(out, u)
}
enclosure.Header.Cancel = out
case "Subject":
enclosure.Header.Subject = strings.Split(h, "Subject=")[1]
case "BodyKey":
enclosure.Header.BodyKey = strings.Split(h, "BodyKey=")[1]
case "BodyKeyPromptSalt":
enclosure.Header.BodyKeyPromptSalt = strings.Split(h, "BodyKeyPromptSalt=")[1]
case "BodyKeyPrompt":
enclosure.Header.BodyKeyPrompt = strings.Split(h, "BodyKeyPrompt=")[1]
case "Identity":
enclosure.Header.Identity = strings.Split(h, "Identity=")[1]
case "EncryptKey":
enclosure.Header.EncryptKey = strings.Split(h, "EncryptKey=")[1]
case "Name":
enclosure.Header.Name = strings.Split(h, "Name=")[1]
case "Description":
enclosure.Header.Description = strings.Split(h, "Description=")[1]
case "Edition":
i, err := strconv.Atoi(strings.TrimRight(strings.Split(h, "=")[1], "\n"))
if err != nil {
log.WithFields(log.Fields{
"at": "(Enclosure) MarshallHeader strconv",
"i": i,
"reason": "conversion error",
}).Fatalf("%s", err)
}
enclosure.Header.Edition = i
case "PublicPosting":
if strings.Contains(strings.Split(h, "PublicPosting=")[1], "true") {
enclosure.Header.PublicPosting = true
}
case "PublicReplies":
if strings.Contains(strings.Split(h, "PublicReplies=")[1], "true") {
enclosure.Header.PublicReplies = true
}
case "AuthorizedKeys":
enclosure.Header.AuthorizedKeys = strings.Split(h, "AuthorizedKeys=")[1:]
case "ManagerKeys":
enclosure.Header.ManagerKeys = strings.Split(h, "ManagerKeys=")[1:]
case "Archives":
var out []syndieuri.URI
r := strings.Split(h, "Archives=")[1:]
for _, arch := range r {
u := syndieuri.URI{}
u.Marshall(arch)
out = append(out, u)
}
enclosure.Header.Archives = out
case "ChannelReadKeys":
enclosure.Header.ChannelReadKeys = strings.Split(h, "ChannelReadKeys=")[1:]
case "Expiration":
enclosure.Header.Expiration = strings.Split(h, "Expiration=")[1]
}
}
} else {
if bytes.Index(bs, []byte("AuthorizationSig=")) > 0 {
apos := bytes.Index(bs, []byte("AuthorizationSig="))
sig := strings.Split(string(bs[apos:]), "AuthorizationSig=")
enclosure.HmacPos = apos
enclosure.AuthorizationSig = strings.TrimSpace(sig[1])
}
if bytes.Index(bs, []byte("AuthenticationSig=")) > 0 {
apos := bytes.Index(bs, []byte("AuthenticationSig="))
sig := strings.Split(string(bs[apos:]), "AuthenticationSig=")
enclosure.AuthenticationSig = strings.TrimSpace(sig[1])
}
rest2 = append(rest2[:], bs...)
}
// TODO: err out here?
}
if err := scanner.Err(); err != nil {
log.WithFields(log.Fields{
"at": "(Enclosure) scanner.Scan",
"enclosure_parsed": scanner.Bytes(),
"reason": "invalid input scanned",
}).Fatalf("%s", err)
}
if bytes.HasPrefix(rest2, []byte("Size=")) {
line := strings.Split(string(rest2)[len("Size="):], "\n")
size, err := strconv.Atoi(line[0])
rest := strings.Join(line[1:], "\n")
if err != nil {
log.WithFields(log.Fields{
"at": "(Enclosure) MarshallTrailer",
"size": size,
"line": line,
"reason": "parsing error",
}).Fatalf("%s", err)
}
enclosure.Message.Size = size
enclosure.Message.Raw = []byte(rest)
} else {
panic("Invalid trailer marshalling attempted")
}
return enclosure
}

View File

@ -1,41 +0,0 @@
package enclosure
import (
"github.com/kpetku/go-syndie/lib/syndieuri"
)
// SyndieHeader holds a Syndie header that contains version and pairs fields:
/*
Author AuthenticationMask TargetChannel PostURI References Tags OverwriteURI ForceNewThread
RefuseReplies Cancel Subject BodyKey BodyKeyPromptSalt BodyKeyPrompt Identity EncryptKey Name
Description Edition PublicPosting PublicReplies AuthorizedKeys ManagerKeys Archives ChannelReadKeys Expiration
*/
type SyndieHeader struct {
Version string
Author string
AuthenticationMask string
TargetChannel string
PostURI syndieuri.URI
References []syndieuri.URI
Tags []string
OverwriteURI syndieuri.URI
ForceNewThread bool
RefuseReplies bool
Cancel []syndieuri.URI
Subject string
BodyKey string
BodyKeyPromptSalt string
BodyKeyPrompt string
Identity string
EncryptKey string
Name string
Description string
Edition int
PublicPosting bool
PublicReplies bool
AuthorizedKeys []string
ManagerKeys []string
Archives []syndieuri.URI
ChannelReadKeys []string
Expiration string
}

View File

@ -1,212 +0,0 @@
package enclosure
import (
"bufio"
"bytes"
"errors"
"os"
"strconv"
"strings"
"github.com/kpetku/go-syndie/lib/syndieuri"
log "github.com/Sirupsen/logrus"
)
func NewEnclosure(f *os.File, err error) (*SyndieHeader, *SyndieTrailer) {
scanner := bufio.NewScanner(f)
scanner.Split(bufio.SplitFunc(doubleNewlineDelimiter))
success := scanner.Scan()
encl := SyndieHeader{}
if validateHeader(&encl, scanner.Bytes()) != nil {
log.Infof("Error from validateHeader! %s", err)
}
scanner.Scan()
tail := SyndieTrailer{}
if validateBody(&tail, scanner.Bytes()) != nil {
log.Infof("Error from validateBody! %s", err)
}
if serr := scanner.Err(); err != nil {
log.Fatal(serr)
}
if !success {
// False on error or EOF. Check error
err = scanner.Err()
if err == nil {
log.Printf("OooF EOF")
} else {
log.Fatal(err)
}
}
return &encl, &tail
}
func validateBody(e *SyndieTrailer, b []byte) error {
if !bytes.Contains(b, []byte("Size=")) {
return errors.New("Invalid Syndie body")
}
position := bytes.Index(b, []byte("\n"))
if position > 0 {
size, err := strconv.Atoi(string(b[5:position])) // 5 is len("Size=")
if err != nil {
log.WithFields(log.Fields{
"at": "(Enclosure) MarshallTrailer",
"size": size,
"line": string(b[5:position]),
"reason": "parsing error",
}).Fatalf("%s", err)
}
e.Size = size
e.Raw = b[position+1:]
e.Body = b
e.AuthenticationSig = bytes.Split(b[bytes.Index(b, []byte("AuthenticationSig=")):], []byte("\n"))[0][18:]
e.AuthorizationSig = bytes.Split(b[bytes.Index(b, []byte("AuthorizationSig=")):], []byte("\n"))[0][17:]
} else {
return errors.New("Flattened corrupted Syndie body...")
}
return nil
}
func validateHeader(e *SyndieHeader, b []byte) error {
for count, line := range bytes.SplitN(b, []byte("\n"), 2) {
if count == 0 {
if !bytes.Contains(line, []byte("Syndie.Message.1.0")) {
return errors.New("Invalid Syndie message")
}
} else {
err := validateHeaderLine(e, line)
if err != nil {
log.Fatalf("%s", err.Error())
}
}
}
return nil
}
func validateHeaderLine(e *SyndieHeader, b []byte) error {
if bytes.Contains(b, []byte("=")) {
split := bytes.SplitN(b, []byte("="), 2)
key := string(split[0])
value := string(split[1])
switch key {
case "Author":
e.Author = value
case "AuthenticationMask":
e.AuthenticationMask = value
case "TargetChannel":
e.TargetChannel = value
case "PostURI":
u := syndieuri.URI{}
u.Marshall(value)
e.PostURI = u
case "References":
var out []syndieuri.URI
r := strings.Fields(value)
for _, ref := range r {
u := syndieuri.URI{}
u.Marshall(ref)
out = append(out, u)
}
e.References = out
case "Tags":
e.Tags = strings.Fields(value)
case "OverwriteURI":
u := syndieuri.URI{}
u.Marshall(value)
e.OverwriteURI = u
case "ForceNewThread":
if strings.Contains(value, "true") {
e.ForceNewThread = true
}
case "RefuseReplies":
if strings.Contains(value, "true") {
e.RefuseReplies = true
}
case "Cancel":
var out []syndieuri.URI
r := strings.Fields(value)
for _, canc := range r {
u := syndieuri.URI{}
u.Marshall(canc)
out = append(out, u)
}
e.Cancel = out
case "Subject":
e.Subject = value
case "BodyKey":
e.BodyKey = value
case "BodyKeyPromptSalt":
e.BodyKeyPromptSalt = value
case "BodyKeyPrompt":
e.BodyKeyPrompt = value
case "Identity":
e.Identity = value
case "EncryptKey":
e.EncryptKey = value
case "Name":
e.Name = value
case "Description":
e.Description = value
case "Edition":
i, err := strconv.Atoi(value)
if err != nil {
log.WithFields(log.Fields{
"at": "(Enclosure) MarshallHeader strconv",
"i": i,
"reason": "conversion error",
}).Fatalf("%s", err)
}
e.Edition = i
case "PublicPosting":
if strings.Contains(value, "true") {
e.PublicPosting = true
}
case "PublicReplies":
if strings.Contains(value, "true") {
e.PublicReplies = true
}
case "AuthorizedKeys":
e.AuthorizedKeys = strings.Fields(value)
case "ManagerKeys":
e.ManagerKeys = strings.Fields(value)
case "Archives":
var out []syndieuri.URI
r := strings.Fields(value)
for _, arch := range r {
u := syndieuri.URI{}
u.Marshall(arch)
out = append(out, u)
}
e.Archives = out
case "ChannelReadKeys":
e.ChannelReadKeys = strings.Fields(value)
case "Expiration":
e.Expiration = value
case "Syndie.MessageType":
// TODO: wrong place for MessageType?
default:
return errors.New("corrupt header key: " + key + " value: " + value)
}
return nil
}
return errors.New("corrupt header")
}
func doubleNewlineDelimiter(data []byte, atEOF bool) (advance int, token []byte, err error) {
if atEOF && len(data) == 0 {
return 0, nil, nil
}
if i := bytes.Index(data, []byte("\n\n")); i >= 0 {
return i + 2, data[0:i], nil
}
if atEOF {
return len(data), data, nil
}
return 0, nil, nil
}

View File

@ -1,122 +0,0 @@
package enclosure
import (
"bytes"
"crypto/aes"
"crypto/cipher"
"crypto/hmac"
"crypto/sha256"
"encoding/binary"
"github.com/kpetku/go-syndie/lib/common"
log "github.com/Sirupsen/logrus"
)
// SyndieTrailer contains a Syndie trailer that contains version and pairs fields
type SyndieTrailer struct {
Size int
Raw []byte
decrypted []byte
AuthorizationSig []byte
AuthenticationSig []byte
Body []byte
EOF int
}
// SyndieTrailerPayload holds the following: rand(nonzero) padding + 0 + internalSize + totalSize + data + rand
type SyndieTrailerPayload struct {
InternalSize int
TotalSize int
Decrypted []byte
DecryptedRaw []byte
IV []byte
HMAC []byte
BodySection []byte
}
// DecryptAES decrypts a SyndieTrailer into a messagePayload
func (trailer *SyndieTrailer) DecryptAES(key string) SyndieTrailerPayload {
var found bool
inner := SyndieTrailerPayload{}
k, err := common.I2PEncoding.DecodeString(key)
if err != nil {
log.WithFields(log.Fields{
"at": "(trailer) DecryptAES, DecodeString",
"key": key,
"reason": "unable to convert key into b64",
}).Fatalf("%s", err)
}
block, err := aes.NewCipher([]byte(k))
if err != nil {
log.WithFields(log.Fields{
"at": "(trailer) DecryptAES, NewCipher",
"key": key,
"block": block,
"reason": "invalid block AES cipher",
}).Fatalf("%s", err)
}
inner.IV = trailer.Raw[0:16]
inner.HMAC = trailer.Raw[trailer.Size-32 : trailer.Size]
decrypter := cipher.NewCBCDecrypter(block, trailer.Raw[:16])
decrypted := make([]byte, trailer.Size+32)
decrypter.CryptBlocks(decrypted, trailer.Raw[16:trailer.Size])
for i := range decrypted {
if !found && decrypted[i] == 0x0 {
is := int(binary.BigEndian.Uint32(decrypted[i+1 : i+5]))
ts := int(binary.BigEndian.Uint32(decrypted[i+5 : i+9]))
if trailer.Size != ts+16 {
log.WithFields(log.Fields{
"at": "(trailer) DecryptAES",
"trailer_size": trailer.Size,
"is": is,
"ts": ts + 16,
"reason": "payload size did not match envelope size",
}).Fatalf("%s", err)
}
inner.InternalSize = is
inner.TotalSize = ts
inner.Decrypted = decrypted[i+9 : i+9+is]
inner.DecryptedRaw = decrypted
var hmacPreKey bytes.Buffer
hmacPreKey.Write(k)
hmacPreKey.Write(trailer.Raw[0:16])
sha := sha256.New()
sha.Write(hmacPreKey.Bytes())
if !verifyHmac256(trailer.Raw[16:trailer.Size-32], trailer.Raw[trailer.Size-32:trailer.Size], sha.Sum(nil)) {
log.WithFields(log.Fields{
"at": "(trailer) DecryptAES, verifyHmac256",
"reason": "invalid HMAC",
}).Fatalf("%s", err)
}
found = true
}
}
return inner
}
func verifyHmac256(stringToVerify []byte, signature []byte, sharedSecret []byte) bool {
h := hmac.New(sha256.New, sharedSecret)
h.Write(stringToVerify)
calculated := h.Sum(nil)
return hmac.Equal(calculated, signature)
}
func colonDelimiter(data []byte, atEOF bool) (advance int, token []byte, err error) {
if atEOF && len(data) == 0 {
return 0, nil, nil
}
if i := bytes.Index(data, []byte{58}); i >= 0 {
return i + 1, data[0:i], nil
}
if atEOF {
return len(data), data, nil
}
return 0, nil, nil
}

View File

@ -1,129 +0,0 @@
package syndieuri
import (
"bytes"
"errors"
"strings"
log "github.com/Sirupsen/logrus"
"github.com/jackpal/bencode-go"
)
/*
URI defines the URIs safely passable within syndie, capable of referencing specific resources.
They contain one of four reference types, plus a bencoded set of attributes:
*/
type URI struct {
RefType string
Name string `bencode:",omitempty"`
Desc string `bencode:",omitempty"`
Tag []string `bencode:",omitempty"`
Author string `bencode:",omitempty"`
Net string `bencode:",omitempty"`
ReadKeyType string `bencode:",omitempty"`
ReadKeyData string `bencode:",omitempty"`
PostKeyType string `bencode:",omitempty"`
PostKeyData string `bencode:",omitempty"`
URL string `bencode:",omitempty"`
Channel string `bencode:",omitempty"`
MessageID int `bencode:",omitempty"`
Page int `bencode:",omitempty"`
Attachment int `bencode:",omitempty"`
Scope []string `bencode:",omitempty"`
PostByScope []string `bencode:",omitempty"`
Age int `bencode:",omitempty"`
AgeLocal int `bencode:",omitempty"`
UnreadOnly bool `bencode:",omitempty"`
TagInclude []string `bencode:",omitempty"`
TagRequire []string `bencode:",omitempty"`
TagExclude []string `bencode:",omitempty"`
TagMessages bool `bencode:",omitempty"`
PageMin int `bencode:",omitempty"`
PageMax int `bencode:",omitempty"`
AttachMin int `bencode:",omitempty"`
AttachMax int `bencode:",omitempty"`
RefMin int `bencode:",omitempty"`
RefMax int `bencode:",omitempty"`
KeyMin int `bencode:",omitempty"`
KeyMax int `bencode:",omitempty"`
Encrypted bool `bencode:",omitempty"`
PBE bool `bencode:",omitempty"`
Private bool `bencode:",omitempty"`
Public bool `bencode:",omitempty"`
Authorized bool `bencode:",omitempty"`
Threaded bool `bencode:",omitempty"`
Keyword string `bencode:",omitempty"`
Body string `bencode:",omitempty"`
}
// colonDelimiter returns data for a scanner delimited by a colon
func colonDelimiter(data []byte, atEOF bool) (advance int, token []byte, err error) {
log.Printf("data was %s", data)
if atEOF && len(data) == 0 {
return 0, nil, nil
}
if i := bytes.Index(data, []byte{58}); i >= 0 {
return i + 1, data[0:i], nil
}
if atEOF {
return len(data), data, nil
}
return 0, nil, nil
}
// trimSyndieURI trims "urn:", "urn:syndie", and "syndie:" from the left of a string
func trimSyndieURI(in string) string {
if strings.HasPrefix(in, "urn:syndie:") {
in = strings.Join(strings.Split(in, "urn:syndie:")[1:], "")
}
if strings.HasPrefix(in, "urn:") {
in = strings.Join(strings.Split(in, "urn:")[1:], "")
}
if strings.HasPrefix(in, "syndie:") {
in = strings.Join(strings.Split(in, "syndie:")[1:], "")
}
return in
}
// prepareURI checks a string for an invalid URI and ommits the refType before bencoding the rest.
func prepareURI(in string) (out string, err error) {
if len(in) < 3 {
return in, errors.New("invalid URI")
}
in = trimSyndieURI(in)
switch strings.Split(strings.ToLower(in), ":")[0] {
case "url", "channel", "search", "archive", "text":
// Drop the RefType to prepare for bencode
return strings.Join(strings.Split(in, ":")[1:], ":"), nil
default:
return in, errors.New("invalid URI refType: " + in)
}
}
// Marshall takes a URI as string and returns a populated URI
func (u *URI) Marshall(s string) *URI {
if len(s) < 3 {
log.WithFields(log.Fields{
"at": "(uri) Marshall",
"reason": "URI was too short to process",
}).Fatalf("URI was too short to process")
return &URI{}
}
s = trimSyndieURI(s)
u.RefType = strings.Split(s, ":")[0]
prepared, err := prepareURI(s)
if err != nil {
panic(err)
}
r := bytes.NewReader([]byte(prepared))
berr := bencode.Unmarshal(r, &u)
if berr != nil {
log.WithFields(log.Fields{
"at": "(uri) Marshall",
"reason": "error while parsing bencode",
}).Infof("%s", berr)
panic(err)
}
return u
}

34
main.go
View File

@ -1,15 +1,43 @@
package main
import (
"flag"
"os"
log "github.com/Sirupsen/logrus"
"github.com/kpetku/go-syndie/syndieutil"
)
func main() {
log.Printf("go-syndie: startup.")
_, err := os.Open(os.Args[1])
var arg string
if len(os.Args) > 0 {
arg = os.Args[1]
}
defaultKey := flag.String("key", "pjvUqwqXVD5Da7pJPVJcYStnfBrWaPqQCPN8Jw8Q-Lw=", "use specified key, default: pjvUqwqXVD5Da7pJPVJcYStnfBrWaPqQCPN8Jw8Q-Lw=")
flag.Parse()
file, err := os.Open(arg)
if err != nil {
log.Fatal(err)
log.Fatalf("Error while opening file %s", err)
}
err2 := syndieutil.ParseBody(file, *defaultKey)
if err2 != nil {
log.Printf("Error reading message: %s", err2.Error())
}
defer file.Close()
/*
current, err := user.Current()
if err != nil {
log.Fatalf("Could not obtain current user")
}
syndieutil.FetchFromDisk(current.HomeDir + "/.syndie/archive/")
*/
}

View File

@ -24,13 +24,13 @@ func ParseBody(input io.Reader, bodyKey string) error {
br := bufio.NewReader(input)
var realSize int
var e MessageHeader
var header MessageHeader
line, lerr := br.ReadString('\n')
if lerr != nil {
return errors.New("invalid message: " + lerr.Error())
}
// search for the magic "Syndie.Message.1." string
// find the magic "Syndie.Message.1." string
if !strings.HasPrefix(line, "Syndie.Message.1.") {
return errors.New("invalid message")
}
@ -52,8 +52,9 @@ func ParseBody(input io.Reader, bodyKey string) error {
realSize = bar
break
}
// do things with the header line(s), just call validateHeaderLine for now
herr := validateHeaderLine(&e, []byte(strings.TrimSpace(line)))
// do things with the header line(s)
// just call validateHeaderLine for now
herr := validateHeaderLine(&header, []byte(strings.TrimSpace(line)))
if herr != nil {
return errors.New("error validating header line: " + line + " error: " + herr.Error())
}