X-Git-Url: http://www.git.cypherpunks.ru/?a=blobdiff_plain;f=src%2Fcmd%2Fnncp-pkt%2Fmain.go;h=c22b1f71038e209bda406fe3c5bf5903420c6291;hb=b47dbfe6687569650fa544a4ecf3e4ea388390cb;hp=aaf0c2dd90c76337818314f4dd192e5cb1c877c1;hpb=04e3fde9391f487e67c67f7f12c019319490658f;p=nncp.git diff --git a/src/cmd/nncp-pkt/main.go b/src/cmd/nncp-pkt/main.go index aaf0c2d..c22b1f7 100644 --- a/src/cmd/nncp-pkt/main.go +++ b/src/cmd/nncp-pkt/main.go @@ -1,6 +1,6 @@ /* NNCP -- Node to Node copy, utilities for store-and-forward data exchange -Copyright (C) 2016-2019 Sergey Matveev +Copyright (C) 2016-2021 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 @@ -29,7 +29,7 @@ import ( xdr "github.com/davecgh/go-xdr/xdr2" "github.com/klauspost/compress/zstd" - "go.cypherpunks.ru/nncp/v5" + "go.cypherpunks.ru/nncp/v8" ) func usage() { @@ -40,6 +40,133 @@ func usage() { fmt.Fprintln(os.Stderr, "Packet is read from stdin.") } +func doPlain(ctx *nncp.Ctx, pkt nncp.Pkt, dump, decompress bool) { + if dump { + bufW := bufio.NewWriter(os.Stdout) + var r io.Reader + r = bufio.NewReader(os.Stdin) + if decompress { + decompressor, err := zstd.NewReader(r) + if err != nil { + log.Fatalln(err) + } + r = decompressor + } + if _, err := io.Copy(bufW, r); err != nil { + log.Fatalln(err) + } + if err := bufW.Flush(); err != nil { + log.Fatalln(err) + } + return + } + payloadType := "unknown" + switch pkt.Type { + case nncp.PktTypeFile: + payloadType = "file" + case nncp.PktTypeFreq: + payloadType = "file request" + case nncp.PktTypeExec: + payloadType = "exec compressed" + case nncp.PktTypeTrns: + payloadType = "transitional" + case nncp.PktTypeExecFat: + payloadType = "exec uncompressed" + case nncp.PktTypeArea: + payloadType = "area" + } + var path string + switch pkt.Type { + case nncp.PktTypeExec, nncp.PktTypeExecFat: + path = string(bytes.Replace( + pkt.Path[:pkt.PathLen], []byte{0}, []byte(" "), -1, + )) + case nncp.PktTypeTrns: + path = nncp.Base32Codec.EncodeToString(pkt.Path[:pkt.PathLen]) + node, err := ctx.FindNode(path) + if err == nil { + path = fmt.Sprintf("%s (%s)", path, node.Name) + } + case nncp.PktTypeArea: + path = nncp.Base32Codec.EncodeToString(pkt.Path[:pkt.PathLen]) + if areaId, err := nncp.AreaIdFromString(path); err == nil { + path = fmt.Sprintf("%s (%s)", path, ctx.AreaName(areaId)) + } + default: + path = string(pkt.Path[:pkt.PathLen]) + } + fmt.Printf( + "Packet type: plain\nPayload type: %s\nNiceness: %s (%d)\nPath: %s\n", + payloadType, nncp.NicenessFmt(pkt.Nice), pkt.Nice, path, + ) + return +} + +func doEncrypted( + ctx *nncp.Ctx, + pktEnc nncp.PktEnc, + dump bool, + beginning []byte, +) { + senderName := "unknown" + senderNode := ctx.Neigh[*pktEnc.Sender] + if senderNode != nil { + senderName = senderNode.Name + } + + recipientName := "unknown" + var area *nncp.Area + recipientNode := ctx.Neigh[*pktEnc.Recipient] + if recipientNode == nil { + area = ctx.AreaId2Area[nncp.AreaId(*pktEnc.Recipient)] + if area != nil { + recipientName = "area " + area.Name + } + } else { + recipientName = recipientNode.Name + } + + if !dump { + fmt.Printf(`Packet type: encrypted +Niceness: %s (%d) +Sender: %s (%s) +Recipient: %s (%s) +`, + nncp.NicenessFmt(pktEnc.Nice), pktEnc.Nice, + pktEnc.Sender, senderName, + pktEnc.Recipient, recipientName, + ) + return + } + if ctx.Self == nil { + log.Fatalln("Config lacks private keys") + } + bufW := bufio.NewWriter(os.Stdout) + var err error + if area == nil { + _, _, _, err = nncp.PktEncRead( + ctx.Self, ctx.Neigh, + io.MultiReader(bytes.NewReader(beginning), bufio.NewReader(os.Stdin)), + bufW, senderNode != nil, nil, + ) + } else { + areaNode := nncp.NodeOur{Id: new(nncp.NodeId), ExchPrv: new([32]byte)} + copy(areaNode.Id[:], area.Id[:]) + copy(areaNode.ExchPrv[:], area.Prv[:]) + _, _, _, err = nncp.PktEncRead( + &areaNode, ctx.Neigh, + io.MultiReader(bytes.NewReader(beginning), bufio.NewReader(os.Stdin)), + bufW, senderNode != nil, nil, + ) + } + if err != nil { + log.Fatalln(err) + } + if err = bufW.Flush(); err != nil { + log.Fatalln(err) + } +} + func main() { var ( overheads = flag.Bool("overheads", false, "Print packet overheads") @@ -49,6 +176,7 @@ func main() { version = flag.Bool("version", false, "Print version information") warranty = flag.Bool("warranty", false, "Print warranty information") ) + log.SetFlags(log.Lshortfile) flag.Usage = usage flag.Parse() if *warranty { @@ -60,6 +188,11 @@ func main() { return } + ctx, err := nncp.CtxFromCmdline(*cfgPath, "", "", false, false, false, false) + if err != nil { + log.Fatalln("Error during initialization:", err) + } + if *overheads { fmt.Printf( "Plain: %d\nEncrypted: %d\nSize: %d\n", @@ -70,97 +203,43 @@ func main() { return } - var err error beginning := make([]byte, nncp.PktOverhead) - if _, err = io.ReadFull(os.Stdin, beginning); err != nil { + if _, err := io.ReadFull(os.Stdin, beginning[:nncp.PktEncOverhead]); err != nil { log.Fatalln("Not enough data to read") } - var pkt nncp.Pkt - _, err = xdr.Unmarshal(bytes.NewReader(beginning), &pkt) - if err == nil && pkt.Magic == nncp.MagicNNCPPv3 { - if *dump { - bufW := bufio.NewWriter(os.Stdout) - var r io.Reader - r = bufio.NewReader(os.Stdin) - if *decompress { - decompressor, err := zstd.NewReader(r) - if err != nil { - log.Fatalln(err) - } - r = decompressor - } - if _, err = io.Copy(bufW, r); err != nil { - log.Fatalln(err) - } - if err = bufW.Flush(); err != nil { - log.Fatalln(err) - } + var pktEnc nncp.PktEnc + if _, err := xdr.Unmarshal(bytes.NewReader(beginning), &pktEnc); err == nil { + switch pktEnc.Magic { + case nncp.MagicNNCPEv1.B: + log.Fatalln(nncp.MagicNNCPEv1.TooOld()) + case nncp.MagicNNCPEv2.B: + log.Fatalln(nncp.MagicNNCPEv2.TooOld()) + case nncp.MagicNNCPEv3.B: + log.Fatalln(nncp.MagicNNCPEv3.TooOld()) + case nncp.MagicNNCPEv4.B: + log.Fatalln(nncp.MagicNNCPEv4.TooOld()) + case nncp.MagicNNCPEv5.B: + log.Fatalln(nncp.MagicNNCPEv5.TooOld()) + case nncp.MagicNNCPEv6.B: + doEncrypted(ctx, pktEnc, *dump, beginning[:nncp.PktEncOverhead]) return } - payloadType := "unknown" - switch pkt.Type { - case nncp.PktTypeFile: - payloadType = "file" - case nncp.PktTypeFreq: - payloadType = "file request" - case nncp.PktTypeExec: - payloadType = "exec" - case nncp.PktTypeTrns: - payloadType = "transitional" - } - var path string - switch pkt.Type { - case nncp.PktTypeExec: - path = string(bytes.Replace( - pkt.Path[:pkt.PathLen], - []byte{0}, - []byte(" "), - -1, - )) - case nncp.PktTypeTrns: - path = nncp.ToBase32(pkt.Path[:pkt.PathLen]) - default: - path = string(pkt.Path[:pkt.PathLen]) - } - fmt.Printf( - "Packet type: plain\nPayload type: %s\nNiceness: %s (%d)\nPath: %s\n", - payloadType, nncp.NicenessFmt(pkt.Nice), pkt.Nice, path, - ) - return } - var pktEnc nncp.PktEnc - _, err = xdr.Unmarshal(bytes.NewReader(beginning), &pktEnc) - if err == nil && pktEnc.Magic == nncp.MagicNNCPEv4 { - if *dump { - ctx, err := nncp.CtxFromCmdline(*cfgPath, "", "", false, false, false, false) - if err != nil { - log.Fatalln("Error during initialization:", err) - } - if ctx.Self == nil { - log.Fatalln("Config lacks private keys") - } - bufW := bufio.NewWriter(os.Stdout) - if _, _, err = nncp.PktEncRead( - ctx.Self, - ctx.Neigh, - io.MultiReader( - bytes.NewReader(beginning), - bufio.NewReader(os.Stdin), - ), - bufW, - ); err != nil { - log.Fatalln(err) - } - if err = bufW.Flush(); err != nil { - log.Fatalln(err) - } + + if _, err := io.ReadFull(os.Stdin, beginning[nncp.PktEncOverhead:]); err != nil { + log.Fatalln("Not enough data to read") + } + var pkt nncp.Pkt + if _, err := xdr.Unmarshal(bytes.NewReader(beginning), &pkt); err == nil { + switch pkt.Magic { + case nncp.MagicNNCPPv1.B: + log.Fatalln(nncp.MagicNNCPPv1.TooOld()) + case nncp.MagicNNCPPv2.B: + log.Fatalln(nncp.MagicNNCPPv2.TooOld()) + case nncp.MagicNNCPPv3.B: + doPlain(ctx, pkt, *dump, *decompress) return } - fmt.Printf( - "Packet type: encrypted\nNiceness: %s (%d)\nSender: %s\nRecipient: %s\n", - nncp.NicenessFmt(pktEnc.Nice), pktEnc.Nice, pktEnc.Sender, pktEnc.Recipient, - ) - return } log.Fatalln("Unable to determine packet type") }