@end table
@verbatim
-$ [fetch|wget] http://www.nncpgo.org/download/nncp-5.1.1.tar.xz
-$ [fetch|wget] http://www.nncpgo.org/download/nncp-5.1.1.tar.xz.sig
-$ gpg --verify nncp-5.1.1.tar.xz.sig nncp-5.1.1.tar.xz
-$ xz --decompress --stdout nncp-5.1.1.tar.xz | tar xf -
-$ make -C nncp-5.1.1 all
+$ [fetch|wget] http://www.nncpgo.org/download/nncp-5.1.2.tar.xz
+$ [fetch|wget] http://www.nncpgo.org/download/nncp-5.1.2.tar.xz.sig
+$ gpg --verify nncp-5.1.2.tar.xz.sig nncp-5.1.2.tar.xz
+$ xz --decompress --stdout nncp-5.1.2.tar.xz | tar xf -
+$ make -C nncp-5.1.2 all
@end verbatim
There is @command{install} make-target respecting @env{DESTDIR}. It will
install binaries and info-documentation:
@verbatim
-# make -C nncp-5.1.1 install PREFIX=/usr/local
+# make -C nncp-5.1.2 install PREFIX=/usr/local
@end verbatim
@multitable {XXXXX} {XXXX-XX-XX} {XXXX KiB} {link sign} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
@headitem Version @tab Date @tab Size @tab Tarball @tab SHA256 checksum
+@item @ref{Release 5.1.1, 5.1.1} @tab 2019-12-01 @tab 1103 KiB
+@tab @url{download/nncp-5.1.1.tar.xz, link} @url{download/nncp-5.1.1.tar.xz.sig, sign}
+@tab @code{B9537678 E5B549BA 6FA0D20D 41B2D4A9 4ED31F2C AB9FAF63 A388D95E 7662A93F}
+
@item @ref{Release 5.1.0, 5.1.0} @tab 2019-11-24 @tab 1103 KiB
@tab @url{download/nncp-5.1.0.tar.xz, link} @url{download/nncp-5.1.0.tar.xz.sig, sign}
@tab @code{6F5B74EC 952EAFEC 2A787463 CE1E808E CC990F03 D46F28E9 A89BAB55 5A2C2214}
You @strong{have to} check downloaded archives integrity and verify
their signature to be sure that you have got trusted, untampered
software. For integrity and authentication of downloaded binaries
-@url{https://www.gnupg.org/, The GNU Privacy Guard} is used. You must
+@url{https://www.gnupg.org/, GNU Privacy Guard} is used. You must
download signature (@file{.sig}) provided with the tarball.
For the very first time you need to import signing public key. It is
Then you could verify tarballs signature:
@verbatim
-$ gpg --verify nncp-5.1.1.tar.xz.sig nncp-5.1.1.tar.xz
+$ gpg --verify nncp-5.1.2.tar.xz.sig nncp-5.1.2.tar.xz
@end verbatim
@node Новости
@section Новости
+@node Релиз 5.1.2
+@subsection Релиз 5.1.2
+@itemize
+
+@item
+Исправлена @strong{критичная} уязвимость: аутентификация online нод
+могла приводить к некорректной идентификации удалённой стороны, позволяя
+скачивать чужие зашифрованные пакеты.
+
+@item
+Исправлена ошибка: в новосозданных конфигурационных файлах, приватный
+публичный ключ Noise были поменяны местами, что приводило к
+невозможности online аутентификации нод.
+
+@item
+Явная синхронизация (fsync) директорий для гарантированного
+переименования файлов.
+
+@end itemize
+
@node Релиз 5.1.1
@subsection Релиз 5.1.1
@itemize
See also this page @ref{Новости, on russian}.
+@node Release 5.1.2
+@section Release 5.1.2
+@itemize
+
+@item
+@strong{Critical} vulnerability: remote peers authentication could lead
+to incorrect identification of remote side, allowing foreign encrypted
+packets downloading.
+
+@item
+Bugfix: private and public Noise keys were swapped in newly created
+configuration files, that lead to inability to authenticate online peers.
+
+@item
+Explicit directories fsync-ing for guaranteed files renaming.
+
+@end itemize
+
@node Release 5.1.1
@section Release 5.1.1
@itemize
git checkout v$release
rm -fr .git
-mod_name=go.cypherpunks.ru/nncp/v5
+mod_name=$(sed -n 's/^module //p' src/go.mod)
mv src src.orig
mkdir -p src/$mod_name
mv src.orig/* src/$mod_name
# $FreeBSD: head/net/nncp/Makefile 517819 2019-11-17 11:51:56Z dmgk $
PORTNAME= nncp
-DISTVERSION= 5.1.1
+DISTVERSION= 5.1.2
CATEGORIES= net
MASTER_SITES= http://www.nncpgo.org/download/
if err = os.Rename(tmp.Name(), dstPath); err != nil {
log.Fatalln("Error during renaming:", err)
}
+ if err = nncp.DirSync(selfPath); err != nil {
+ log.Fatalln("Error during syncing:", err)
+ }
}
}
ctx.LogI("nncp-bundle", nncp.SdsAdd(sds, nncp.SDS{
nncp.ToBase32(nodeOur.ExchPrv[:]),
nncp.ToBase32(nodeOur.SignPub[:]),
nncp.ToBase32(nodeOur.SignPrv[:]),
- nncp.ToBase32(nodeOur.NoisePub[:]),
nncp.ToBase32(nodeOur.NoisePrv[:]),
+ nncp.ToBase32(nodeOur.NoisePub[:]),
nodeOur.Id.String(),
nncp.ToBase32(nodeOur.ExchPub[:]),
nncp.ToBase32(nodeOur.SignPub[:]),
nncp.ToBase32(nodeOur.ExchPrv[:]),
nncp.ToBase32(nodeOur.SignPub[:]),
nncp.ToBase32(nodeOur.SignPrv[:]),
- nncp.ToBase32(nodeOur.NoisePub[:]),
nncp.ToBase32(nodeOur.NoisePrv[:]),
+ nncp.ToBase32(nodeOur.NoisePub[:]),
nodeOur.Id.String(),
nncp.ToBase32(nodeOur.ExchPub[:]),
nncp.ToBase32(nodeOur.SignPub[:]),
if err = os.Rename(tmp.Name(), dstPath); err != nil {
log.Fatalln(err)
}
+ if err = nncp.DirSync(mainDir); err != nil {
+ log.Fatalln(err)
+ }
ctx.LogI("nncp-reass", nncp.SDS{"path": path}, "done")
return !hasErrors
}
isBad = true
continue
}
+ if err = nncp.DirSync(dstPath); err != nil {
+ ctx.LogE("nncp-xfer", nncp.SdsAdd(sds, nncp.SDS{"err": err}), "sync")
+ isBad = true
+ continue
+ }
os.Remove(filepath.Join(dstPath, pktName+".part"))
delete(sds, "tmp")
ctx.LogI("nncp-xfer", nncp.SdsAdd(sds, nncp.SDS{
case "nncp-rm":
msg += "removing " + sds["file"]
case "call-start":
- msg = fmt.Sprintf("Connected to %s", nodeS)
+ msg = fmt.Sprintf("Connection to %s", nodeS)
+ if err, exists := sds["err"]; exists {
+ msg += ": " + err
+ }
case "call-finish":
rx, err := strconv.ParseUint(sds["rxbytes"], 10, 64)
if err != nil {
humanize.IBytes(uint64(rx)), humanize.IBytes(uint64(rxs)),
humanize.IBytes(uint64(tx)), humanize.IBytes(uint64(txs)),
)
+ case "sp-start":
+ if nodeS == "" {
+ msg += "SP"
+ if peer, exists := sds["peer"]; exists {
+ msg += fmt.Sprintf(": %s", peer)
+ }
+ } else {
+ nice, err := NicenessParse(sds["nice"])
+ if err != nil {
+ return s
+ }
+ msg += fmt.Sprintf("SP with %s (nice %s)", nodeS, NicenessFmt(nice))
+ }
+ if len(rem) > 0 {
+ msg += ": " + rem
+ }
+ if err, exists := sds["err"]; exists {
+ msg += ": " + err
+ }
+
case "sp-info":
nice, err := NicenessParse(sds["nice"])
if err != nil {
var sp SPRaw
n, err := xdr.UnmarshalLimited(src, &sp, 1<<17)
if err != nil {
+ ue := err.(*xdr.UnmarshalError)
+ if ue.Err == io.EOF {
+ return nil, ue.Err
+ }
return nil, err
}
state.RxLastSeen = time.Now()
}
var node *Node
- for _, node = range state.Ctx.Neigh {
- if subtle.ConstantTimeCompare(state.hs.PeerStatic(), node.NoisePub[:]) == 1 {
+ for _, n := range state.Ctx.Neigh {
+ if subtle.ConstantTimeCompare(state.hs.PeerStatic(), n.NoisePub[:]) == 1 {
+ node = n
break
}
}
sdsp["xx"] = string(TRx)
sdsp["hash"] = ToBase32(file.Hash[:])
sdsp["size"] = strconv.Itoa(len(file.Payload))
- filePath := filepath.Join(
+ dirToSync := filepath.Join(
state.Ctx.Spool,
state.Node.Id.String(),
string(TRx),
- ToBase32(file.Hash[:]),
)
+ filePath := filepath.Join(dirToSync, ToBase32(file.Hash[:]))
state.Ctx.LogD("sp-file", sdsp, "opening part")
fd, err := os.OpenFile(
filePath+PartSuffix,
return
}
state.Ctx.LogI("sp-done", SdsAdd(sdsp, SDS{"xx": string(TRx)}), "")
- os.Rename(filePath+PartSuffix, filePath)
+ if err = os.Rename(filePath+PartSuffix, filePath); err != nil {
+ state.Ctx.LogE("sp-file", SdsAdd(sdsp, SDS{"err": err}), "rename")
+ return
+ }
+ if err = DirSync(dirToSync); err != nil {
+ state.Ctx.LogE("sp-file", SdsAdd(sdsp, SDS{"err": err}), "sync")
+ return
+ }
state.Lock()
delete(state.infosTheir, *file.Hash)
state.Unlock()
os.Remove(tmp.Fd.Name())
}
+func DirSync(dirPath string) error {
+ fd, err := os.Open(dirPath)
+ if err != nil {
+ return err
+ }
+ err = fd.Sync()
+ if err != nil {
+ fd.Close()
+ return err
+ }
+ return fd.Close()
+}
+
func (tmp *TmpFileWHash) Commit(dir string) error {
var err error
if err = os.MkdirAll(dir, os.FileMode(0777)); err != nil {
tmp.Fd.Close()
checksum := ToBase32(tmp.Hsh.Sum(nil))
tmp.ctx.LogD("tmp", SDS{"src": tmp.Fd.Name(), "dst": checksum}, "commit")
- return os.Rename(tmp.Fd.Name(), filepath.Join(dir, checksum))
+ if err = os.Rename(tmp.Fd.Name(), filepath.Join(dir, checksum)); err != nil {
+ return err
+ }
+ return DirSync(dir)
}
ctx.LogE("rx", SdsAdd(sds, SDS{"err": err}), "rename")
isBad = true
}
+ if err = DirSync(*incoming); err != nil {
+ ctx.LogE("rx", SdsAdd(sds, SDS{"err": err}), "sync")
+ isBad = true
+ }
delete(sds, "tmp")
}
ctx.LogI("rx", sds, "")