X-Git-Url: http://www.git.cypherpunks.ru/?a=blobdiff_plain;f=src%2Fcypherpunks.ru%2Fnncp%2Ftoss.go;h=c180ed9554c6c1d6b9c5b4fc4fc068f0df596546;hb=dd92823db3d72fb21a4c712a7fb052dce16443dd;hp=eb44f26a9878e2d95a3d7ab0c87f3354c620ab2c;hpb=ded811e9e4736ad182636fe7bf8221ac9a95e08b;p=nncp.git diff --git a/src/cypherpunks.ru/nncp/toss.go b/src/cypherpunks.ru/nncp/toss.go index eb44f26..c180ed9 100644 --- a/src/cypherpunks.ru/nncp/toss.go +++ b/src/cypherpunks.ru/nncp/toss.go @@ -1,11 +1,10 @@ /* NNCP -- Node to Node copy, utilities for store-and-forward data exchange -Copyright (C) 2016-2018 Sergey Matveev +Copyright (C) 2016-2019 Sergey Matveev This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. +the Free Software Foundation, version 3 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -20,6 +19,7 @@ package nncp import ( "bufio" + "bytes" "compress/zlib" "fmt" "io" @@ -36,6 +36,7 @@ import ( "github.com/davecgh/go-xdr/xdr2" "github.com/dustin/go-humanize" "golang.org/x/crypto/blake2b" + "golang.org/x/crypto/poly1305" ) const ( @@ -51,7 +52,11 @@ func newNotification(fromTo *FromToYAML, subject string) io.Reader { )) } -func (ctx *Ctx) Toss(nodeId *NodeId, nice uint8, dryRun, doSeen bool) bool { +func (ctx *Ctx) Toss( + nodeId *NodeId, + nice uint8, + dryRun, doSeen, noFile, noFreq, noExec, noTrns bool, +) bool { isBad := false for job := range ctx.Jobs(nodeId, TRx) { pktName := filepath.Base(job.Fd.Name()) @@ -83,45 +88,60 @@ func (ctx *Ctx) Toss(nodeId *NodeId, nice uint8, dryRun, doSeen bool) bool { var pkt Pkt var err error var pktSize int64 + var pktSizeBlocks int64 if _, err = xdr.Unmarshal(pipeR, &pkt); err != nil { ctx.LogE("rx", SdsAdd(sds, SDS{"err": err}), "unmarshal") isBad = true goto Closing } - pktSize = job.Size - PktEncOverhead - PktOverhead + pktSize = job.Size - PktEncOverhead - PktOverhead - PktSizeOverhead + pktSizeBlocks = pktSize / (EncBlkSize + poly1305.TagSize) + if pktSize%(EncBlkSize+poly1305.TagSize) != 0 { + pktSize -= poly1305.TagSize + } + pktSize -= pktSizeBlocks * poly1305.TagSize sds["size"] = strconv.FormatInt(pktSize, 10) ctx.LogD("rx", sds, "taken") switch pkt.Type { - case PktTypeMail: - recipients := string(pkt.Path[:int(pkt.PathLen)]) + case PktTypeExec: + if noExec { + goto Closing + } + path := bytes.Split(pkt.Path[:int(pkt.PathLen)], []byte{0}) + handle := string(path[0]) + args := make([]string, 0, len(path)-1) + for _, p := range path[1:] { + args = append(args, string(p)) + } sds := SdsAdd(sds, SDS{ - "type": "mail", - "dst": recipients, + "type": "exec", + "dst": strings.Join(append([]string{handle}, args...), " "), }) decompressor, err := zlib.NewReader(pipeR) if err != nil { log.Fatalln(err) } sender := ctx.Neigh[*job.PktEnc.Sender] - sendmail := sender.Sendmail - if len(sendmail) == 0 { - ctx.LogE("rx", SdsAdd(sds, SDS{"err": "No sendmail configured"}), "") + cmdline, exists := sender.Exec[handle] + if !exists || len(cmdline) == 0 { + ctx.LogE("rx", SdsAdd(sds, SDS{"err": "No handle found"}), "") isBad = true goto Closing } if !dryRun { cmd := exec.Command( - sendmail[0], - append( - sendmail[1:len(sendmail)], - strings.Split(recipients, " ")..., - )..., + cmdline[0], + append(cmdline[1:len(cmdline)], args...)..., + ) + cmd.Env = append( + cmd.Env, + "NNCP_SELF="+ctx.Self.Id.String(), + "NNCP_SENDER="+sender.Id.String(), + "NNCP_NICE="+strconv.Itoa(int(pkt.Nice)), ) - cmd.Env = append(cmd.Env, "NNCP_SENDER="+sender.Id.String()) - cmd.Env = append(cmd.Env, "NNCP_NICE="+strconv.Itoa(int(pkt.Nice))) cmd.Stdin = decompressor if err = cmd.Run(); err != nil { - ctx.LogE("rx", SdsAdd(sds, SDS{"err": err}), "sendmail") + ctx.LogE("rx", SdsAdd(sds, SDS{"err": err}), "handle") isBad = true goto Closing } @@ -139,6 +159,9 @@ func (ctx *Ctx) Toss(nodeId *NodeId, nice uint8, dryRun, doSeen bool) bool { } } case PktTypeFile: + if noFile { + goto Closing + } dst := string(pkt.Path[:int(pkt.PathLen)]) sds := SdsAdd(sds, SDS{"type": "file", "dst": dst}) if filepath.IsAbs(dst) { @@ -160,21 +183,31 @@ func (ctx *Ctx) Toss(nodeId *NodeId, nice uint8, dryRun, doSeen bool) bool { } if !dryRun { tmp, err := ioutil.TempFile(dir, "nncp-file") - sds["tmp"] = tmp.Name() - ctx.LogD("rx", sds, "created") if err != nil { ctx.LogE("rx", SdsAdd(sds, SDS{"err": err}), "mktemp") isBad = true goto Closing } + sds["tmp"] = tmp.Name() + ctx.LogD("rx", sds, "created") bufW := bufio.NewWriter(tmp) if _, err = io.Copy(bufW, pipeR); err != nil { ctx.LogE("rx", SdsAdd(sds, SDS{"err": err}), "copy") isBad = true goto Closing } - bufW.Flush() - tmp.Sync() + if err = bufW.Flush(); err != nil { + tmp.Close() + ctx.LogE("rx", SdsAdd(sds, SDS{"err": err}), "copy") + isBad = true + goto Closing + } + if err = tmp.Sync(); err != nil { + tmp.Close() + ctx.LogE("rx", SdsAdd(sds, SDS{"err": err}), "copy") + isBad = true + goto Closing + } tmp.Close() dstPathOrig := filepath.Join(*incoming, dst) dstPath := dstPathOrig @@ -208,8 +241,8 @@ func (ctx *Ctx) Toss(nodeId *NodeId, nice uint8, dryRun, doSeen bool) bool { ctx.LogE("rx", SdsAdd(sds, SDS{"err": err}), "remove") isBad = true } - sendmail := ctx.Neigh[*ctx.SelfId].Sendmail - if ctx.NotifyFile != nil { + sendmail, exists := ctx.Neigh[*ctx.SelfId].Exec["sendmail"] + if exists && len(sendmail) > 0 && ctx.NotifyFile != nil { cmd := exec.Command( sendmail[0], append(sendmail[1:len(sendmail)], ctx.NotifyFile.To)..., @@ -224,6 +257,9 @@ func (ctx *Ctx) Toss(nodeId *NodeId, nice uint8, dryRun, doSeen bool) bool { } } case PktTypeFreq: + if noFreq { + goto Closing + } src := string(pkt.Path[:int(pkt.PathLen)]) if filepath.IsAbs(src) { ctx.LogE("rx", sds, "non-relative source path") @@ -282,8 +318,8 @@ func (ctx *Ctx) Toss(nodeId *NodeId, nice uint8, dryRun, doSeen bool) bool { ctx.LogE("rx", SdsAdd(sds, SDS{"err": err}), "remove") isBad = true } - if ctx.NotifyFreq != nil { - sendmail := ctx.Neigh[*ctx.SelfId].Sendmail + sendmail, exists := ctx.Neigh[*ctx.SelfId].Exec["sendmail"] + if exists && len(sendmail) > 0 && ctx.NotifyFreq != nil { cmd := exec.Command( sendmail[0], append(sendmail[1:len(sendmail)], ctx.NotifyFreq.To)..., @@ -297,6 +333,9 @@ func (ctx *Ctx) Toss(nodeId *NodeId, nice uint8, dryRun, doSeen bool) bool { } } case PktTypeTrns: + if noTrns { + goto Closing + } dst := new([blake2b.Size256]byte) copy(dst[:], pkt.Path[:int(pkt.PathLen)]) nodeId := NodeId(*dst)