gnunet-go

GNUnet Bindings for Go
Log | Files | Refs | README | LICENSE

commit 169fda0a59d7e51a1b29985d12df3fcdb9584de9
parent 8e4c1501b82cdbba6c545a4b49eb5b65050579ba
Author: Bernd Fix <brf@hoi-polloi.org>
Date:   Wed, 12 Feb 2020 18:01:12 +0100

Code and documentation changes based on review feedback.

Diffstat:
ACOPYING | 2++
Msrc/cmd/gnunet-service-gns-go/main.go | 26++++++++++++++++++++++++--
Msrc/gnunet/config/config.go | 39+++++++++++++++++++++------------------
Msrc/gnunet/config/config_test.go | 18++++++++++++++++++
Msrc/gnunet/config/gnunet-config.json | 4+---
Msrc/gnunet/core/peer.go | 18++++++++++++++++++
Msrc/gnunet/crypto/gns.go | 18++++++++++++++++++
Msrc/gnunet/crypto/gns_test.go | 18++++++++++++++++++
Msrc/gnunet/crypto/hash.go | 18++++++++++++++++++
Msrc/gnunet/crypto/key_derivation.go | 18++++++++++++++++++
Msrc/gnunet/crypto/key_derivation_test.go | 18++++++++++++++++++
Msrc/gnunet/crypto/key_exchange.go | 18++++++++++++++++++
Msrc/gnunet/crypto/key_exchange_test.go | 18++++++++++++++++++
Msrc/gnunet/crypto/keys_test.go | 18++++++++++++++++++
Msrc/gnunet/crypto/signature.go | 18++++++++++++++++++
Msrc/gnunet/crypto/symmetric.go | 18++++++++++++++++++
Msrc/gnunet/enums/dht.go | 18++++++++++++++++++
Msrc/gnunet/enums/gns.go | 18++++++++++++++++++
Msrc/gnunet/enums/signature.go | 18++++++++++++++++++
Msrc/gnunet/go.mod | 6+++++-
Msrc/gnunet/go.sum | 19+++++++++++++++++--
Msrc/gnunet/message/const.go | 18++++++++++++++++++
Msrc/gnunet/message/factory.go | 22++++++++++++++++++++++
Msrc/gnunet/message/message.go | 18++++++++++++++++++
Msrc/gnunet/message/msg_core.go | 18++++++++++++++++++
Msrc/gnunet/message/msg_dht.go | 18++++++++++++++++++
Msrc/gnunet/message/msg_gns.go | 149+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/gnunet/message/msg_namecache.go | 100+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/gnunet/message/msg_transport.go | 18++++++++++++++++++
Msrc/gnunet/message/types.go | 18++++++++++++++++++
Msrc/gnunet/modules.go | 18++++++++++++++++++
Msrc/gnunet/service/client.go | 18++++++++++++++++++
Dsrc/gnunet/service/gns/block.go | 185-------------------------------------------------------------------------------
Msrc/gnunet/service/gns/block_handler.go | 48+++++++++++++++++++++++++++++++++---------------
Msrc/gnunet/service/gns/box.go | 18++++++++++++++++++
Msrc/gnunet/service/gns/dns.go | 83++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
Msrc/gnunet/service/gns/module.go | 99++++++++++++++++++++++++++++++++++++++++++++++++-------------------------------
Msrc/gnunet/service/gns/service.go | 161++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------------
Msrc/gnunet/service/namecache/module.go | 23+++++++++++++++++++++--
Msrc/gnunet/service/service.go | 32+++++++++++++++++++++++++++++---
Msrc/gnunet/transport/channel.go | 38+++++++++++++++++++++++++++++++++-----
Msrc/gnunet/transport/channel_netw.go | 18++++++++++++++++++
Msrc/gnunet/transport/channel_test.go | 18++++++++++++++++++
Msrc/gnunet/transport/connection.go | 18++++++++++++++++++
Msrc/gnunet/transport/session.go | 18++++++++++++++++++
Msrc/gnunet/util/address.go | 18++++++++++++++++++
Msrc/gnunet/util/array.go | 18++++++++++++++++++
Msrc/gnunet/util/base32.go | 18++++++++++++++++++
Msrc/gnunet/util/base32_test.go | 18++++++++++++++++++
Msrc/gnunet/util/format.go | 18++++++++++++++++++
Asrc/gnunet/util/fs.go | 43+++++++++++++++++++++++++++++++++++++++++++
Msrc/gnunet/util/id.go | 18++++++++++++++++++
Msrc/gnunet/util/misc.go | 18++++++++++++++++++
Msrc/gnunet/util/peer_id.go | 18++++++++++++++++++
Msrc/gnunet/util/rnd.go | 18++++++++++++++++++
Msrc/gnunet/util/time.go | 18++++++++++++++++++
56 files changed, 1432 insertions(+), 331 deletions(-)

diff --git a/COPYING b/COPYING @@ -0,0 +1 @@ +LICENSE +\ No newline at end of file diff --git a/src/cmd/gnunet-service-gns-go/main.go b/src/cmd/gnunet-service-gns-go/main.go @@ -1,3 +1,21 @@ +// This file is part of gnunet-go, a GNUnet-implementation in Golang. +// Copyright (C) 2019, 2020 Bernd Fix >Y< +// +// gnunet-go is free software: you can redistribute it and/or modify it +// under the terms of the GNU Affero General Public License as published +// by the Free Software Foundation, either version 3 of the License, +// or (at your option) any later version. +// +// gnunet-go is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// +// SPDX-License-Identifier: AGPL3.0-or-later + package main import ( @@ -14,7 +32,13 @@ import ( ) func main() { + defer func() { + logger.Println(logger.INFO, "[gns] Bye.") + // flush last messages + logger.Flush() + }() logger.Println(logger.INFO, "[gns] Starting service...") + var ( cfgFile string srvEndp string @@ -76,6 +100,4 @@ loop: // terminating service srv.Stop() - // wait for logger to flush last messages - time.Sleep(5 * time.Second) } diff --git a/src/gnunet/config/config.go b/src/gnunet/config/config.go @@ -1,3 +1,21 @@ +// This file is part of gnunet-go, a GNUnet-implementation in Golang. +// Copyright (C) 2019, 2020 Bernd Fix >Y< +// +// gnunet-go is free software: you can redistribute it and/or modify it +// under the terms of the GNU Affero General Public License as published +// by the Free Software Foundation, either version 3 of the License, +// or (at your option) any later version. +// +// gnunet-go is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// +// SPDX-License-Identifier: AGPL3.0-or-later + package config import ( @@ -7,9 +25,6 @@ import ( "regexp" "strings" - "gnunet/util" - - "github.com/bfix/gospel/crypto/ed25519" "github.com/bfix/gospel/logger" ) @@ -18,21 +33,9 @@ import ( // GNSConfig type GNSConfig struct { - Endpoint string `json:"endpoint"` // end-point of GNS service - DHTReplLevel int `json:"dhtReplLevel"` // DHT replication level - RootZones map[string]string `json:"rootZones"` // pre-configured root zones -} - -// GetRootZoneKey returns the zone key (PKEY) for a pre-configured root with given name. -func (gns *GNSConfig) GetRootZoneKey(name string) *ed25519.PublicKey { - // lookup key in the dictionary - if dStr, ok := gns.RootZones[name]; ok { - if data, err := util.DecodeStringToBinary(dStr, 32); err == nil { - return ed25519.NewPublicKeyFromBytes(data) - } - } - // no pkey found. - return nil + Endpoint string `json:"endpoint"` // end-point of GNS service + DHTReplLevel int `json:"dhtReplLevel"` // DHT replication level + MaxDepth int `json:"maxDepth"` // maximum recursion depth in resolution } /////////////////////////////////////////////////////////////////////// diff --git a/src/gnunet/config/config_test.go b/src/gnunet/config/config_test.go @@ -1,3 +1,21 @@ +// This file is part of gnunet-go, a GNUnet-implementation in Golang. +// Copyright (C) 2019, 2020 Bernd Fix >Y< +// +// gnunet-go is free software: you can redistribute it and/or modify it +// under the terms of the GNU Affero General Public License as published +// by the Free Software Foundation, either version 3 of the License, +// or (at your option) any later version. +// +// gnunet-go is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// +// SPDX-License-Identifier: AGPL3.0-or-later + package config import ( diff --git a/src/gnunet/config/gnunet-config.json b/src/gnunet/config/gnunet-config.json @@ -9,9 +9,7 @@ "gns": { "endpoint": "unix+${RT_SYS}/gnunet-service-gns-go.sock+perm=0770", "dhtReplLevel": 10, - "rootZones": { - "home": "ACAB23DC3SEECJORPHQNVRH965A6N74B1M37S721IG4RBQ15PJLL" - } + "maxDepth": 250 }, "namecache": { "endpoint": "unix+${RT_SYS}/gnunet-service-namecache.sock" diff --git a/src/gnunet/core/peer.go b/src/gnunet/core/peer.go @@ -1,3 +1,21 @@ +// This file is part of gnunet-go, a GNUnet-implementation in Golang. +// Copyright (C) 2019, 2020 Bernd Fix >Y< +// +// gnunet-go is free software: you can redistribute it and/or modify it +// under the terms of the GNU Affero General Public License as published +// by the Free Software Foundation, either version 3 of the License, +// or (at your option) any later version. +// +// gnunet-go is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// +// SPDX-License-Identifier: AGPL3.0-or-later + package core import ( diff --git a/src/gnunet/crypto/gns.go b/src/gnunet/crypto/gns.go @@ -1,3 +1,21 @@ +// This file is part of gnunet-go, a GNUnet-implementation in Golang. +// Copyright (C) 2019, 2020 Bernd Fix >Y< +// +// gnunet-go is free software: you can redistribute it and/or modify it +// under the terms of the GNU Affero General Public License as published +// by the Free Software Foundation, either version 3 of the License, +// or (at your option) any later version. +// +// gnunet-go is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// +// SPDX-License-Identifier: AGPL3.0-or-later + package crypto import ( diff --git a/src/gnunet/crypto/gns_test.go b/src/gnunet/crypto/gns_test.go @@ -1,3 +1,21 @@ +// This file is part of gnunet-go, a GNUnet-implementation in Golang. +// Copyright (C) 2019, 2020 Bernd Fix >Y< +// +// gnunet-go is free software: you can redistribute it and/or modify it +// under the terms of the GNU Affero General Public License as published +// by the Free Software Foundation, either version 3 of the License, +// or (at your option) any later version. +// +// gnunet-go is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// +// SPDX-License-Identifier: AGPL3.0-or-later + package crypto import ( diff --git a/src/gnunet/crypto/hash.go b/src/gnunet/crypto/hash.go @@ -1,3 +1,21 @@ +// This file is part of gnunet-go, a GNUnet-implementation in Golang. +// Copyright (C) 2019, 2020 Bernd Fix >Y< +// +// gnunet-go is free software: you can redistribute it and/or modify it +// under the terms of the GNU Affero General Public License as published +// by the Free Software Foundation, either version 3 of the License, +// or (at your option) any later version. +// +// gnunet-go is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// +// SPDX-License-Identifier: AGPL3.0-or-later + package crypto import ( diff --git a/src/gnunet/crypto/key_derivation.go b/src/gnunet/crypto/key_derivation.go @@ -1,3 +1,21 @@ +// This file is part of gnunet-go, a GNUnet-implementation in Golang. +// Copyright (C) 2019, 2020 Bernd Fix >Y< +// +// gnunet-go is free software: you can redistribute it and/or modify it +// under the terms of the GNU Affero General Public License as published +// by the Free Software Foundation, either version 3 of the License, +// or (at your option) any later version. +// +// gnunet-go is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// +// SPDX-License-Identifier: AGPL3.0-or-later + package crypto import ( diff --git a/src/gnunet/crypto/key_derivation_test.go b/src/gnunet/crypto/key_derivation_test.go @@ -1,3 +1,21 @@ +// This file is part of gnunet-go, a GNUnet-implementation in Golang. +// Copyright (C) 2019, 2020 Bernd Fix >Y< +// +// gnunet-go is free software: you can redistribute it and/or modify it +// under the terms of the GNU Affero General Public License as published +// by the Free Software Foundation, either version 3 of the License, +// or (at your option) any later version. +// +// gnunet-go is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// +// SPDX-License-Identifier: AGPL3.0-or-later + package crypto import ( diff --git a/src/gnunet/crypto/key_exchange.go b/src/gnunet/crypto/key_exchange.go @@ -1,3 +1,21 @@ +// This file is part of gnunet-go, a GNUnet-implementation in Golang. +// Copyright (C) 2019, 2020 Bernd Fix >Y< +// +// gnunet-go is free software: you can redistribute it and/or modify it +// under the terms of the GNU Affero General Public License as published +// by the Free Software Foundation, either version 3 of the License, +// or (at your option) any later version. +// +// gnunet-go is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// +// SPDX-License-Identifier: AGPL3.0-or-later + package crypto import ( diff --git a/src/gnunet/crypto/key_exchange_test.go b/src/gnunet/crypto/key_exchange_test.go @@ -1,3 +1,21 @@ +// This file is part of gnunet-go, a GNUnet-implementation in Golang. +// Copyright (C) 2019, 2020 Bernd Fix >Y< +// +// gnunet-go is free software: you can redistribute it and/or modify it +// under the terms of the GNU Affero General Public License as published +// by the Free Software Foundation, either version 3 of the License, +// or (at your option) any later version. +// +// gnunet-go is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// +// SPDX-License-Identifier: AGPL3.0-or-later + package crypto import ( diff --git a/src/gnunet/crypto/keys_test.go b/src/gnunet/crypto/keys_test.go @@ -1,3 +1,21 @@ +// This file is part of gnunet-go, a GNUnet-implementation in Golang. +// Copyright (C) 2019, 2020 Bernd Fix >Y< +// +// gnunet-go is free software: you can redistribute it and/or modify it +// under the terms of the GNU Affero General Public License as published +// by the Free Software Foundation, either version 3 of the License, +// or (at your option) any later version. +// +// gnunet-go is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// +// SPDX-License-Identifier: AGPL3.0-or-later + package crypto import ( diff --git a/src/gnunet/crypto/signature.go b/src/gnunet/crypto/signature.go @@ -1,3 +1,21 @@ +// This file is part of gnunet-go, a GNUnet-implementation in Golang. +// Copyright (C) 2019, 2020 Bernd Fix >Y< +// +// gnunet-go is free software: you can redistribute it and/or modify it +// under the terms of the GNU Affero General Public License as published +// by the Free Software Foundation, either version 3 of the License, +// or (at your option) any later version. +// +// gnunet-go is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// +// SPDX-License-Identifier: AGPL3.0-or-later + package crypto // SignaturePurpose is the GNUnet data structure used as header for signed data. diff --git a/src/gnunet/crypto/symmetric.go b/src/gnunet/crypto/symmetric.go @@ -1,3 +1,21 @@ +// This file is part of gnunet-go, a GNUnet-implementation in Golang. +// Copyright (C) 2019, 2020 Bernd Fix >Y< +// +// gnunet-go is free software: you can redistribute it and/or modify it +// under the terms of the GNU Affero General Public License as published +// by the Free Software Foundation, either version 3 of the License, +// or (at your option) any later version. +// +// gnunet-go is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// +// SPDX-License-Identifier: AGPL3.0-or-later + package crypto import ( diff --git a/src/gnunet/enums/dht.go b/src/gnunet/enums/dht.go @@ -1,3 +1,21 @@ +// This file is part of gnunet-go, a GNUnet-implementation in Golang. +// Copyright (C) 2019, 2020 Bernd Fix >Y< +// +// gnunet-go is free software: you can redistribute it and/or modify it +// under the terms of the GNU Affero General Public License as published +// by the Free Software Foundation, either version 3 of the License, +// or (at your option) any later version. +// +// gnunet-go is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// +// SPDX-License-Identifier: AGPL3.0-or-later + package enums // DHT flags and settings diff --git a/src/gnunet/enums/gns.go b/src/gnunet/enums/gns.go @@ -1,3 +1,21 @@ +// This file is part of gnunet-go, a GNUnet-implementation in Golang. +// Copyright (C) 2019, 2020 Bernd Fix >Y< +// +// gnunet-go is free software: you can redistribute it and/or modify it +// under the terms of the GNU Affero General Public License as published +// by the Free Software Foundation, either version 3 of the License, +// or (at your option) any later version. +// +// gnunet-go is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// +// SPDX-License-Identifier: AGPL3.0-or-later + package enums // GNS constants diff --git a/src/gnunet/enums/signature.go b/src/gnunet/enums/signature.go @@ -1,3 +1,21 @@ +// This file is part of gnunet-go, a GNUnet-implementation in Golang. +// Copyright (C) 2019, 2020 Bernd Fix >Y< +// +// gnunet-go is free software: you can redistribute it and/or modify it +// under the terms of the GNU Affero General Public License as published +// by the Free Software Foundation, either version 3 of the License, +// or (at your option) any later version. +// +// gnunet-go is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// +// SPDX-License-Identifier: AGPL3.0-or-later + package enums // Signature purpose constants diff --git a/src/gnunet/go.mod b/src/gnunet/go.mod @@ -2,4 +2,8 @@ module gnunet go 1.12 -require github.com/bfix/gospel v0.0.0-20190831192707-26682cc943e5 +require ( + github.com/bfix/gospel v0.0.0-20190922182041-6fcd6d4fd449 + github.com/miekg/dns v1.1.26 + golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392 +) diff --git a/src/gnunet/go.sum b/src/gnunet/go.sum @@ -1,10 +1,25 @@ -github.com/bfix/gospel v0.0.0-20190831192707-26682cc943e5 h1:vPrWvbQmjjEaWseuni9K7ffKzYLBLPbK27oHw5DvTAY= -github.com/bfix/gospel v0.0.0-20190831192707-26682cc943e5/go.mod h1:RQYETFV9SP+VriIsHVqCntRpSbbRvCBnNTtbUl9NAKA= +github.com/bfix/gospel v0.0.0-20190922182041-6fcd6d4fd449 h1:oIq3s14sMh1sq791v9VpR+GJvhVGbvuOWlfTjruRTDQ= +github.com/bfix/gospel v0.0.0-20190922182041-6fcd6d4fd449/go.mod h1:RQYETFV9SP+VriIsHVqCntRpSbbRvCBnNTtbUl9NAKA= +github.com/miekg/dns v1.1.26 h1:gPxPSwALAeHJSjarOs00QjVdV9QoBvc1D2ujQUr5BzU= +github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190829043050-9756ffdc2472 h1:Gv7RPwsi3eZ2Fgewe3CBsuOebPwO27PoXzRpJPsvSSM= golang.org/x/crypto v0.0.0-20190829043050-9756ffdc2472/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392 h1:ACG4HJsFiNMf47Y4PeRoebLNy/2lXT9EtprMuTFWt1M= +golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190923162816-aa69164e4478 h1:l5EDrHhldLYb3ZRHDUhXF7Om7MvYXnkV9/iQNo1lX6g= +golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe h1:6fAMxZRR6sl1Uq8U61gxU+kPTs2tR8uOySCbBP7BN/M= +golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/src/gnunet/message/const.go b/src/gnunet/message/const.go @@ -1,3 +1,21 @@ +// This file is part of gnunet-go, a GNUnet-implementation in Golang. +// Copyright (C) 2019, 2020 Bernd Fix >Y< +// +// gnunet-go is free software: you can redistribute it and/or modify it +// under the terms of the GNU Affero General Public License as published +// by the Free Software Foundation, either version 3 of the License, +// or (at your option) any later version. +// +// gnunet-go is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// +// SPDX-License-Identifier: AGPL3.0-or-later + package message import ( diff --git a/src/gnunet/message/factory.go b/src/gnunet/message/factory.go @@ -1,3 +1,21 @@ +// This file is part of gnunet-go, a GNUnet-implementation in Golang. +// Copyright (C) 2019, 2020 Bernd Fix >Y< +// +// gnunet-go is free software: you can redistribute it and/or modify it +// under the terms of the GNU Affero General Public License as published +// by the Free Software Foundation, either version 3 of the License, +// or (at your option) any later version. +// +// gnunet-go is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// +// SPDX-License-Identifier: AGPL3.0-or-later + package message import ( @@ -59,6 +77,10 @@ func NewEmptyMessage(msgType uint16) (Message, error) { return NewNamecacheLookupMsg(nil), nil case NAMECACHE_LOOKUP_BLOCK_RESPONSE: return NewNamecacheLookupResultMsg(), nil + case NAMECACHE_BLOCK_CACHE: + return NewNamecacheCacheMsg(nil), nil + case NAMECACHE_BLOCK_CACHE_RESPONSE: + return NewNamecacheCacheResponseMsg(), nil } return nil, errors.New(fmt.Sprintf("Unknown message type %d", msgType)) } diff --git a/src/gnunet/message/message.go b/src/gnunet/message/message.go @@ -1,3 +1,21 @@ +// This file is part of gnunet-go, a GNUnet-implementation in Golang. +// Copyright (C) 2019, 2020 Bernd Fix >Y< +// +// gnunet-go is free software: you can redistribute it and/or modify it +// under the terms of the GNU Affero General Public License as published +// by the Free Software Foundation, either version 3 of the License, +// or (at your option) any later version. +// +// gnunet-go is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// +// SPDX-License-Identifier: AGPL3.0-or-later + package message import ( diff --git a/src/gnunet/message/msg_core.go b/src/gnunet/message/msg_core.go @@ -1,3 +1,21 @@ +// This file is part of gnunet-go, a GNUnet-implementation in Golang. +// Copyright (C) 2019, 2020 Bernd Fix >Y< +// +// gnunet-go is free software: you can redistribute it and/or modify it +// under the terms of the GNU Affero General Public License as published +// by the Free Software Foundation, either version 3 of the License, +// or (at your option) any later version. +// +// gnunet-go is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// +// SPDX-License-Identifier: AGPL3.0-or-later + package message import ( diff --git a/src/gnunet/message/msg_dht.go b/src/gnunet/message/msg_dht.go @@ -1,3 +1,21 @@ +// This file is part of gnunet-go, a GNUnet-implementation in Golang. +// Copyright (C) 2019, 2020 Bernd Fix >Y< +// +// gnunet-go is free software: you can redistribute it and/or modify it +// under the terms of the GNU Affero General Public License as published +// by the Free Software Foundation, either version 3 of the License, +// or (at your option) any later version. +// +// gnunet-go is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// +// SPDX-License-Identifier: AGPL3.0-or-later + package message import ( diff --git a/src/gnunet/message/msg_gns.go b/src/gnunet/message/msg_gns.go @@ -1,14 +1,39 @@ +// This file is part of gnunet-go, a GNUnet-implementation in Golang. +// Copyright (C) 2019, 2020 Bernd Fix >Y< +// +// gnunet-go is free software: you can redistribute it and/or modify it +// under the terms of the GNU Affero General Public License as published +// by the Free Software Foundation, either version 3 of the License, +// or (at your option) any later version. +// +// gnunet-go is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// +// SPDX-License-Identifier: AGPL3.0-or-later + package message import ( "fmt" + "gnunet/crypto" "gnunet/enums" "gnunet/util" + "github.com/bfix/gospel/crypto/ed25519" + "github.com/bfix/gospel/data" "github.com/bfix/gospel/logger" ) +var ( + ErrBlockNotDecrypted = fmt.Errorf("GNS block not decrypted") +) + //---------------------------------------------------------------------- // GNS_LOOKUP //---------------------------------------------------------------------- @@ -73,6 +98,130 @@ func (msg *GNSLookupMsg) Header() *MessageHeader { // GNS_LOOKUP_RESULT //---------------------------------------------------------------------- +// GNSRecordSet ist the GNUnet data structure for a list of resource records +// in a GNSBlock. As part of GNUnet messages, the record set is padded so that +// the binary size of (records||padding) is the smallest power of two. +type GNSRecordSet struct { + Count uint32 `order:"big"` // number of resource records + Records []*GNSResourceRecord `size:"Count"` // list of resource records + Padding []byte `size:"*"` // padding +} + +// NewGNSRecordSet returns an empty resource record set. +func NewGNSRecordSet() *GNSRecordSet { + return &GNSRecordSet{ + Count: 0, + Records: make([]*GNSResourceRecord, 0), + Padding: make([]byte, 0), + } +} + +// AddRecord to append a resource record to the set. +func (rs *GNSRecordSet) AddRecord(rec *GNSResourceRecord) { + rs.Count++ + rs.Records = append(rs.Records, rec) +} + +// SignedBlockData: signed and encrypted list of resource records stored +// in a GNSRecordSet +type SignedBlockData struct { + Purpose *crypto.SignaturePurpose // Size and purpose of signature (8 bytes) + Expire util.AbsoluteTime // Expiration time of the block. + EncData []byte `size:"*"` // encrypted GNSRecordSet + + // transient data (not serialized) + data []byte // decrypted GNSRecord set +} + +// GNSBlock is the result of GNS lookups for a given label in a zone. +// An encrypted and signed container for GNS resource records that represents +// the "atomic" data structure associated with a GNS label in a given zone. +type GNSBlock struct { + Signature []byte `size:"64"` // Signature of the block. + DerivedKey []byte `size:"32"` // Derived key used for signing + Block *SignedBlockData + + // transient data (not serialized) + checked bool // block integrity checked + verified bool // block signature verified (internal) + decrypted bool // block data decrypted (internal) +} + +// String returns the human-readable representation of a GNSBlock +func (b *GNSBlock) String() string { + return fmt.Sprintf("GNSBlock{Verified=%v,Decrypted=%v,data=[%d]}", + b.verified, b.decrypted, len(b.Block.EncData)) +} + +// Records returns the list of resource records in a block. +func (b *GNSBlock) Records() ([]*GNSResourceRecord, error) { + // check if block is decrypted + if !b.decrypted { + return nil, ErrBlockNotDecrypted + } + // parse block data into record set + rs := NewGNSRecordSet() + if err := data.Unmarshal(rs, b.Block.data); err != nil { + return nil, err + } + return rs.Records, nil +} + +// Verify the integrity of the block data from a signature. +func (b *GNSBlock) Verify(zoneKey *ed25519.PublicKey, label string) (err error) { + // Integrity check performed + b.checked = true + + // verify derived key + dkey := ed25519.NewPublicKeyFromBytes(b.DerivedKey) + dkey2 := crypto.DerivePublicKey(zoneKey, label, "gns") + if !dkey.Q.Equals(dkey2.Q) { + return fmt.Errorf("Invalid signature key for GNS Block") + } + // verify signature + var ( + sig *ed25519.EcSignature + buf []byte + ok bool + ) + if sig, err = ed25519.NewEcSignatureFromBytes(b.Signature); err != nil { + return + } + if buf, err = data.Marshal(b.Block); err != nil { + return + } + if ok, err = dkey.EcVerify(buf, sig); err == nil && !ok { + err = fmt.Errorf("Signature verification failed for GNS block") + } + b.verified = true + return +} + +// Decrypt block data with a key/iv combination derived from (PKEY,label) +func (b *GNSBlock) Decrypt(zoneKey *ed25519.PublicKey, label string) (err error) { + // decrypt payload + b.Block.data, err = crypto.DecryptBlock(b.Block.EncData, zoneKey, label) + b.decrypted = true + return +} + +// NewGNSBlock instantiates an empty GNS block +func NewGNSBlock() *GNSBlock { + return &GNSBlock{ + Signature: make([]byte, 64), + DerivedKey: make([]byte, 32), + Block: &SignedBlockData{ + Purpose: new(crypto.SignaturePurpose), + Expire: *new(util.AbsoluteTime), + EncData: nil, + data: nil, + }, + checked: false, + verified: false, + decrypted: false, + } +} + // GNSResourceRecord is the GNUnet-specific representation of resource // records (not to be confused with DNS resource records). type GNSResourceRecord struct { diff --git a/src/gnunet/message/msg_namecache.go b/src/gnunet/message/msg_namecache.go @@ -1,3 +1,21 @@ +// This file is part of gnunet-go, a GNUnet-implementation in Golang. +// Copyright (C) 2019, 2020 Bernd Fix >Y< +// +// gnunet-go is free software: you can redistribute it and/or modify it +// under the terms of the GNU Affero General Public License as published +// by the Free Software Foundation, either version 3 of the License, +// or (at your option) any later version. +// +// gnunet-go is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// +// SPDX-License-Identifier: AGPL3.0-or-later + package message import ( @@ -82,3 +100,85 @@ func (m *NamecacheLookupResultMsg) String() string { func (msg *NamecacheLookupResultMsg) Header() *MessageHeader { return &MessageHeader{msg.MsgSize, msg.MsgType} } + +//---------------------------------------------------------------------- +// NAMECACHE_CACHE_BLOCK +//---------------------------------------------------------------------- + +// NamecacheCacheMsg +type NamecacheCacheMsg struct { + MsgSize uint16 `order:"big"` // total size of message + MsgType uint16 `order:"big"` // NAMECACHE_CACHE_BLOCK (433) + Id uint32 `order:"big"` // Request Id + Expire util.AbsoluteTime // Expiration time + Signature []byte `size:"64"` // ECDSA signature + DerivedKey []byte `size:"32"` // Derived public key + EncData []byte `size:"*"` // Encrypted block data +} + +// NewNamecacheLookupMsg creates a new default message. +func NewNamecacheCacheMsg(block *GNSBlock) *NamecacheCacheMsg { + msg := &NamecacheCacheMsg{ + MsgSize: 108, + MsgType: NAMECACHE_BLOCK_CACHE, + Id: 0, + Expire: *new(util.AbsoluteTime), + Signature: make([]byte, 64), + DerivedKey: make([]byte, 32), + EncData: make([]byte, 0), + } + if block != nil { + msg.Expire = block.Block.Expire + copy(msg.Signature, block.Signature) + copy(msg.DerivedKey, block.DerivedKey) + size := len(block.Block.EncData) + msg.EncData = make([]byte, size) + copy(msg.EncData, block.Block.EncData) + msg.MsgSize += uint16(size) + } + return msg +} + +// String returns a human-readable representation of the message. +func (m *NamecacheCacheMsg) String() string { + return fmt.Sprintf("NewNamecacheCacheMsg{id=%d,expire=%s}", + m.Id, m.Expire) +} + +// Header returns the message header in a separate instance. +func (msg *NamecacheCacheMsg) Header() *MessageHeader { + return &MessageHeader{msg.MsgSize, msg.MsgType} +} + +//---------------------------------------------------------------------- +// NAMECACHE_BLOCK_CACHE_RESPONSE +//---------------------------------------------------------------------- + +// NamecacheCacheResponseMsg +type NamecacheCacheResponseMsg struct { + MsgSize uint16 `order:"big"` // total size of message + MsgType uint16 `order:"big"` // NAMECACHE_LOOKUP_BLOCK_RESPONSE (432) + Id uint32 `order:"big"` // Request Id + Result int32 `order:"big"` // Result code +} + +// NewNamecacheCacheResponseMsg creates a new default message. +func NewNamecacheCacheResponseMsg() *NamecacheCacheResponseMsg { + return &NamecacheCacheResponseMsg{ + MsgSize: 12, + MsgType: NAMECACHE_BLOCK_CACHE_RESPONSE, + Id: 0, + Result: 0, + } +} + +// String returns a human-readable representation of the message. +func (m *NamecacheCacheResponseMsg) String() string { + return fmt.Sprintf("NamecacheCacheResponseMsg{id=%d,result=%d}", + m.Id, m.Result) +} + +// Header returns the message header in a separate instance. +func (msg *NamecacheCacheResponseMsg) Header() *MessageHeader { + return &MessageHeader{msg.MsgSize, msg.MsgType} +} diff --git a/src/gnunet/message/msg_transport.go b/src/gnunet/message/msg_transport.go @@ -1,3 +1,21 @@ +// This file is part of gnunet-go, a GNUnet-implementation in Golang. +// Copyright (C) 2019, 2020 Bernd Fix >Y< +// +// gnunet-go is free software: you can redistribute it and/or modify it +// under the terms of the GNU Affero General Public License as published +// by the Free Software Foundation, either version 3 of the License, +// or (at your option) any later version. +// +// gnunet-go is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// +// SPDX-License-Identifier: AGPL3.0-or-later + package message import ( diff --git a/src/gnunet/message/types.go b/src/gnunet/message/types.go @@ -1,3 +1,21 @@ +// This file is part of gnunet-go, a GNUnet-implementation in Golang. +// Copyright (C) 2019, 2020 Bernd Fix >Y< +// +// gnunet-go is free software: you can redistribute it and/or modify it +// under the terms of the GNU Affero General Public License as published +// by the Free Software Foundation, either version 3 of the License, +// or (at your option) any later version. +// +// gnunet-go is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// +// SPDX-License-Identifier: AGPL3.0-or-later + package message // GNUnet message types diff --git a/src/gnunet/modules.go b/src/gnunet/modules.go @@ -1,3 +1,21 @@ +// This file is part of gnunet-go, a GNUnet-implementation in Golang. +// Copyright (C) 2019, 2020 Bernd Fix >Y< +// +// gnunet-go is free software: you can redistribute it and/or modify it +// under the terms of the GNU Affero General Public License as published +// by the Free Software Foundation, either version 3 of the License, +// or (at your option) any later version. +// +// gnunet-go is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// +// SPDX-License-Identifier: AGPL3.0-or-later + //====================================================================== // Standalone (all-in-one) implementation of GNUnet: // ------------------------------------------------- diff --git a/src/gnunet/service/client.go b/src/gnunet/service/client.go @@ -1,3 +1,21 @@ +// This file is part of gnunet-go, a GNUnet-implementation in Golang. +// Copyright (C) 2019, 2020 Bernd Fix >Y< +// +// gnunet-go is free software: you can redistribute it and/or modify it +// under the terms of the GNU Affero General Public License as published +// by the Free Software Foundation, either version 3 of the License, +// or (at your option) any later version. +// +// gnunet-go is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// +// SPDX-License-Identifier: AGPL3.0-or-later + package service import ( diff --git a/src/gnunet/service/gns/block.go b/src/gnunet/service/gns/block.go @@ -1,185 +0,0 @@ -package gns - -import ( - "fmt" - - "gnunet/crypto" - "gnunet/enums" - "gnunet/message" - "gnunet/util" - - "github.com/bfix/gospel/crypto/ed25519" - "github.com/bfix/gospel/data" -) - -var ( - ErrBlockNotDecrypted = fmt.Errorf("GNS block not decrypted") -) - -//====================================================================== -// GNS block: An encrypted and signed container for GNS resource records -// that represents the "atomic" data structure associated with a GNS -// label in a given zone. -//====================================================================== - -// SignedBlockData: signed and encrypted list of resource records stored -// in a GNSRecordSet -type SignedBlockData struct { - Purpose *crypto.SignaturePurpose // Size and purpose of signature (8 bytes) - Expire util.AbsoluteTime // Expiration time of the block. - EncData []byte `size:"*"` // encrypted GNSRecordSet - - // transient data (not serialized) - data []byte // unencrypted GNSRecord set -} - -// GNSBlock is the result of GNS lookups for a given label in a zone. -type GNSBlock struct { - Signature []byte `size:"64"` // Signature of the block. - DerivedKey []byte `size:"32"` // Derived key used for signing - Block *SignedBlockData - - // transient data (not serialized) - checked bool // block integrity checked - verified bool // block signature verified (internal) - decrypted bool // block data decrypted (internal) -} - -// String returns the human-readable representation of a GNSBlock -func (b *GNSBlock) String() string { - return fmt.Sprintf("GNSBlock{Verified=%v,Decrypted=%v,data=[%d]}", - b.verified, b.decrypted, len(b.Block.EncData)) -} - -// Records returns the list of resource records in a block. -func (b *GNSBlock) Records() ([]*message.GNSResourceRecord, error) { - // check if block is decrypted - if !b.decrypted { - return nil, ErrBlockNotDecrypted - } - // parse block data into record set - rs := NewGNSRecordSet() - if err := data.Unmarshal(rs, b.Block.data); err != nil { - return nil, err - } - return rs.Records, nil -} - -// Verify the integrity of the block data from a signature. -func (b *GNSBlock) Verify(zoneKey *ed25519.PublicKey, label string) (err error) { - // Integrity check performed - b.checked = true - - // verify derived key - dkey := ed25519.NewPublicKeyFromBytes(b.DerivedKey) - dkey2 := crypto.DerivePublicKey(zoneKey, label, "gns") - if !dkey.Q.Equals(dkey2.Q) { - return fmt.Errorf("Invalid signature key for GNS Block") - } - // verify signature - var ( - sig *ed25519.EcSignature - buf []byte - ok bool - ) - if sig, err = ed25519.NewEcSignatureFromBytes(b.Signature); err != nil { - return - } - if buf, err = data.Marshal(b.Block); err != nil { - return - } - if ok, err = dkey.EcVerify(buf, sig); err == nil && !ok { - err = fmt.Errorf("Signature verification failed for GNS block") - } - b.verified = true - return -} - -// Decrypt block data with a key/iv combination derived from (PKEY,label) -func (b *GNSBlock) Decrypt(zoneKey *ed25519.PublicKey, label string) (err error) { - // decrypt payload - b.Block.data, err = crypto.DecryptBlock(b.Block.EncData, zoneKey, label) - b.decrypted = true - return -} - -// NewGNSBlock instantiates an empty GNS block -func NewGNSBlock() *GNSBlock { - return &GNSBlock{ - Signature: make([]byte, 64), - DerivedKey: make([]byte, 32), - Block: &SignedBlockData{ - Purpose: new(crypto.SignaturePurpose), - Expire: *new(util.AbsoluteTime), - EncData: nil, - data: nil, - }, - checked: false, - verified: false, - decrypted: false, - } -} - -//---------------------------------------------------------------------- -// GNSRecordSet -//---------------------------------------------------------------------- - -// GNSRecordSet ist the GNUnet data structure for a list of resource records -// in a GNSBlock. As part of GNUnet messages, the record set is padded so that -// the binary size of (records||padding) is the smallest power of two. -type GNSRecordSet struct { - Count uint32 `order:"big"` // number of resource records - Records []*message.GNSResourceRecord `size:"Count"` // list of resource records - Padding []byte `size:"*"` // padding -} - -// NewGNSRecordSet returns an empty resource record set. -func NewGNSRecordSet() *GNSRecordSet { - return &GNSRecordSet{ - Count: 0, - Records: make([]*message.GNSResourceRecord, 0), - Padding: make([]byte, 0), - } -} - -// AddRecord to append a resource record to the set. -func (rs *GNSRecordSet) AddRecord(rec *message.GNSResourceRecord) { - rs.Count++ - rs.Records = append(rs.Records, rec) -} - -//====================================================================== -// List of resource records types (for GNS/DNS queries) -//====================================================================== - -// RRTypeList is a list of integers representing RR types. -type RRTypeList []int - -// Initialize a new type list with given type values -func NewRRTypeList(args ...int) (res RRTypeList) { - for _, val := range args { - // if GNS_TYPE_ANY is encountered, it becomes the sole type - if val == enums.GNS_TYPE_ANY { - res = make(RRTypeList, 1) - res[0] = val - return - } - res = append(res, val) - } - return -} - -// HasType returns true if the type is included in the list -func (tl RRTypeList) HasType(t int) bool { - // return true if type is GNS_TYPE_ANY - if tl[0] == enums.GNS_TYPE_ANY { - return true - } - // check for type in list - for _, val := range tl { - if val == t { - return true - } - } - return false -} diff --git a/src/gnunet/service/gns/block_handler.go b/src/gnunet/service/gns/block_handler.go @@ -1,3 +1,21 @@ +// This file is part of gnunet-go, a GNUnet-implementation in Golang. +// Copyright (C) 2019, 2020 Bernd Fix >Y< +// +// gnunet-go is free software: you can redistribute it and/or modify it +// under the terms of the GNU Affero General Public License as published +// by the Free Software Foundation, either version 3 of the License, +// or (at your option) any later version. +// +// gnunet-go is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// +// SPDX-License-Identifier: AGPL3.0-or-later + package gns import ( @@ -61,7 +79,7 @@ type BlockHandler interface { // Records returns a list of RR of the given types associated with // the custom handler - Records(kind RRTypeList) *GNSRecordSet + Records(kind RRTypeList) *message.GNSRecordSet // Name returns the human-readable name of the handler Name() string @@ -236,8 +254,8 @@ func (h *PkeyHandler) Coexist(cm util.CounterMap) bool { } // Records returns a list of RR of the given type associated with this handler -func (h *PkeyHandler) Records(kind RRTypeList) *GNSRecordSet { - rs := NewGNSRecordSet() +func (h *PkeyHandler) Records(kind RRTypeList) *message.GNSRecordSet { + rs := message.NewGNSRecordSet() if kind.HasType(enums.GNS_TYPE_PKEY) { rs.AddRecord(h.rec) } @@ -311,8 +329,8 @@ func (h *Gns2DnsHandler) Coexist(cm util.CounterMap) bool { } // Records returns a list of RR of the given type associated with this handler -func (h *Gns2DnsHandler) Records(kind RRTypeList) *GNSRecordSet { - rs := NewGNSRecordSet() +func (h *Gns2DnsHandler) Records(kind RRTypeList) *message.GNSRecordSet { + rs := message.NewGNSRecordSet() if kind.HasType(enums.GNS_TYPE_GNS2DNS) { for _, rec := range h.recs { rs.AddRecord(rec) @@ -381,8 +399,8 @@ func (h *BoxHandler) Coexist(cm util.CounterMap) bool { } // Records returns a list of RR of the given type associated with this handler -func (h *BoxHandler) Records(kind RRTypeList) *GNSRecordSet { - rs := NewGNSRecordSet() +func (h *BoxHandler) Records(kind RRTypeList) *message.GNSRecordSet { + rs := message.NewGNSRecordSet() for _, box := range h.boxes { if kind.HasType(int(box.Type)) { // valid box found: assemble new resource record. @@ -451,8 +469,8 @@ func (h *LehoHandler) Coexist(cm util.CounterMap) bool { } // Records returns a list of RR of the given type associated with this handler -func (h *LehoHandler) Records(kind RRTypeList) *GNSRecordSet { - rs := NewGNSRecordSet() +func (h *LehoHandler) Records(kind RRTypeList) *message.GNSRecordSet { + rs := message.NewGNSRecordSet() if kind.HasType(enums.GNS_TYPE_LEHO) { rs.AddRecord(h.rec) } @@ -504,13 +522,13 @@ func (h *CnameHandler) AddRecord(rec *message.GNSResourceRecord, labels []string // Coexist return a flag indicating how a resource record of a given type // is to be treated (see BlockHandler interface) func (h *CnameHandler) Coexist(cm util.CounterMap) bool { - // anything goes - return true + // only a single CNAME allowed + return len(cm) == 1 && cm.Num(enums.GNS_TYPE_DNS_CNAME) == 1 } // Records returns a list of RR of the given type associated with this handler -func (h *CnameHandler) Records(kind RRTypeList) *GNSRecordSet { - rs := NewGNSRecordSet() +func (h *CnameHandler) Records(kind RRTypeList) *message.GNSRecordSet { + rs := message.NewGNSRecordSet() if kind.HasType(enums.GNS_TYPE_DNS_CNAME) { rs.AddRecord(h.rec) } @@ -563,8 +581,8 @@ func (h *VpnHandler) Coexist(cm util.CounterMap) bool { } // Records returns a list of RR of the given type associated with this handler -func (h *VpnHandler) Records(kind RRTypeList) *GNSRecordSet { - rs := NewGNSRecordSet() +func (h *VpnHandler) Records(kind RRTypeList) *message.GNSRecordSet { + rs := message.NewGNSRecordSet() if kind.HasType(enums.GNS_TYPE_VPN) { rs.AddRecord(h.rec) } diff --git a/src/gnunet/service/gns/box.go b/src/gnunet/service/gns/box.go @@ -1,3 +1,21 @@ +// This file is part of gnunet-go, a GNUnet-implementation in Golang. +// Copyright (C) 2019, 2020 Bernd Fix >Y< +// +// gnunet-go is free software: you can redistribute it and/or modify it +// under the terms of the GNU Affero General Public License as published +// by the Free Software Foundation, either version 3 of the License, +// or (at your option) any later version. +// +// gnunet-go is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// +// SPDX-License-Identifier: AGPL3.0-or-later + package gns import ( diff --git a/src/gnunet/service/gns/dns.go b/src/gnunet/service/gns/dns.go @@ -1,3 +1,21 @@ +// This file is part of gnunet-go, a GNUnet-implementation in Golang. +// Copyright (C) 2019, 2020 Bernd Fix >Y< +// +// gnunet-go is free software: you can redistribute it and/or modify it +// under the terms of the GNU Affero General Public License as published +// by the Free Software Foundation, either version 3 of the License, +// or (at your option) any later version. +// +// gnunet-go is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// +// SPDX-License-Identifier: AGPL3.0-or-later + package gns import ( @@ -22,6 +40,57 @@ var ( ErrNoDNSResults = fmt.Errorf("No valid DNS results") ) +//---------------------------------------------------------------------- +// List of resource records types (for GNS/DNS queries) +//---------------------------------------------------------------------- + +// RRTypeList is a list of integers representing RR types. +type RRTypeList []int + +// Initialize a new type list with given type values +func NewRRTypeList(args ...int) (res RRTypeList) { + for _, val := range args { + // if GNS_TYPE_ANY is encountered, it becomes the sole type + if val == enums.GNS_TYPE_ANY { + res = make(RRTypeList, 1) + res[0] = val + return + } + res = append(res, val) + } + // if no types are passed, mode ANY is set. + if len(res) == 0 { + res = make(RRTypeList, 1) + res[0] = enums.GNS_TYPE_ANY + return + } + return +} + +// IsAny returns true if no type is filtered. +func (tl RRTypeList) IsAny() bool { + return tl[0] == enums.GNS_TYPE_ANY +} + +// HasType returns true if the type is included in the list +func (tl RRTypeList) HasType(t int) bool { + // return true if type is GNS_TYPE_ANY + if tl[0] == enums.GNS_TYPE_ANY { + return true + } + // check for type in list + for _, val := range tl { + if val == t { + return true + } + } + return false +} + +//---------------------------------------------------------------------- +// Helper functions +//---------------------------------------------------------------------- + // Convert DNS name from its binary representation [RFC1034]: // A string is a sequence of a (len,chars...) tupels terminated by a (len=0,). // The name parts are concatenated with "." as separator. @@ -45,7 +114,7 @@ func DNSNameFromBytes(b []byte, offset int) (int, string) { return pos + 1, str } -func QueryDNS(id int, name string, server net.IP, kind RRTypeList) *GNSRecordSet { +func QueryDNS(id int, name string, server net.IP, kind RRTypeList) *message.GNSRecordSet { // get default nameserver if not defined. if server == nil { server = net.IPv4(8, 8, 8, 8) @@ -90,7 +159,7 @@ func QueryDNS(id int, name string, server net.IP, kind RRTypeList) *GNSRecordSet logger.Printf(logger.ERROR, "[dns][%d] No results\n", id) return nil } - set := NewGNSRecordSet() + set := message.NewGNSRecordSet() for _, record := range in.Answer { // check if answer record is of requested type if kind.HasType(int(record.Header().Rrtype)) { @@ -126,14 +195,18 @@ func QueryDNS(id int, name string, server net.IP, kind RRTypeList) *GNSRecordSet return nil } +//---------------------------------------------------------------------- +// GNSModule methods +//---------------------------------------------------------------------- + // ResolveDNS resolves a name in DNS. Multiple DNS servers are queried in // parallel; the first result delivered by any of the servers is returned // as the result list of matching resource records. -func (gns *GNSModule) ResolveDNS(name string, servers []string, kind RRTypeList, pkey *ed25519.PublicKey) (set *GNSRecordSet, err error) { +func (gns *GNSModule) ResolveDNS(name string, servers []string, kind RRTypeList, pkey *ed25519.PublicKey, depth int) (set *message.GNSRecordSet, err error) { logger.Printf(logger.DBG, "[dns] Resolution of '%s' starting...\n", name) // start DNS queries concurrently - res := make(chan *GNSRecordSet) + res := make(chan *message.GNSRecordSet) running := 0 for _, srv := range servers { // check if srv is an IPv4/IPv6 address @@ -142,7 +215,7 @@ func (gns *GNSModule) ResolveDNS(name string, servers []string, kind RRTypeList, if addr == nil { // no, it is a name... try to resolve an IP address from the name query := NewRRTypeList(enums.GNS_TYPE_DNS_A, enums.GNS_TYPE_DNS_AAAA) - if set, err = gns.ResolveUnknown(srv, pkey, query); err != nil { + if set, err = gns.ResolveUnknown(srv, nil, pkey, query, depth+1); err != nil { logger.Printf(logger.ERROR, "[dns] Can't resolve NS server '%s': %s\n", srv, err.Error()) continue } diff --git a/src/gnunet/service/gns/module.go b/src/gnunet/service/gns/module.go @@ -1,3 +1,21 @@ +// This file is part of gnunet-go, a GNUnet-implementation in Golang. +// Copyright (C) 2019, 2020 Bernd Fix >Y< +// +// gnunet-go is free software: you can redistribute it and/or modify it +// under the terms of the GNU Affero General Public License as published +// by the Free Software Foundation, either version 3 of the License, +// or (at your option) any later version. +// +// gnunet-go is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// +// SPDX-License-Identifier: AGPL3.0-or-later + package gns import ( @@ -20,7 +38,8 @@ import ( // Error codes var ( - ErrUnknownTLD = fmt.Errorf("Unknown TLD in name") + ErrUnknownTLD = fmt.Errorf("Unknown TLD in name") + ErrGNSRecursionExceeded = fmt.Errorf("GNS recursion depth exceeded") ) //---------------------------------------------------------------------- @@ -92,15 +111,18 @@ func NewQuery(pkey *ed25519.PublicKey, label string) *Query { type GNSModule struct { // Use function references for calls to methods in other modules: // - LookupLocal func(query *Query) (*GNSBlock, error) - StoreLocal func(query *Query, block *GNSBlock) error - LookupRemote func(query *Query) (*GNSBlock, error) - GetLocalZone func(name string) (*ed25519.PublicKey, error) + LookupLocal func(query *Query) (*message.GNSBlock, error) + StoreLocal func(block *message.GNSBlock) error + LookupRemote func(query *Query) (*message.GNSBlock, error) } // Resolve a GNS name with multiple labels. If pkey is not nil, the name // is interpreted as "relative to current zone". -func (gns *GNSModule) Resolve(path string, pkey *ed25519.PublicKey, kind RRTypeList, mode int) (set *GNSRecordSet, err error) { +func (gns *GNSModule) Resolve(path string, pkey *ed25519.PublicKey, kind RRTypeList, mode int, depth int) (set *message.GNSRecordSet, err error) { + // check for recursion depth + if depth > config.Cfg.GNS.MaxDepth { + return nil, ErrGNSRecursionExceeded + } // get the labels in reverse order names := util.ReverseStringList(strings.Split(path, ".")) logger.Printf(logger.DBG, "[gns] Resolver called for %v\n", names) @@ -108,39 +130,28 @@ func (gns *GNSModule) Resolve(path string, pkey *ed25519.PublicKey, kind RRTypeL // check for relative path if pkey != nil { //resolve relative path - return gns.ResolveRelative(names, pkey, kind, mode) + return gns.ResolveRelative(names, pkey, kind, mode, depth) } // resolve absolute path - return gns.ResolveAbsolute(names, kind, mode) + return gns.ResolveAbsolute(names, kind, mode, depth) } // Resolve a fully qualified GNS absolute name (with multiple labels). -func (gns *GNSModule) ResolveAbsolute(labels []string, kind RRTypeList, mode int) (set *GNSRecordSet, err error) { +func (gns *GNSModule) ResolveAbsolute(labels []string, kind RRTypeList, mode int, depth int) (set *message.GNSRecordSet, err error) { // get the zone key for the TLD - // (1) check if TLD is a PKEY pkey := gns.GetZoneKey(labels[0]) if pkey == nil { - // (2) check if TLD is in our local config - pkey = config.Cfg.GNS.GetRootZoneKey(labels[0]) - } - if pkey == nil { - // (3) check if TLD is one of our identities - pkey, err = gns.GetLocalZone(labels[0]) - } - if pkey == nil { - if err == nil { - err = ErrUnknownTLD - } - // (4) we can't resolve this TLD + // we can't resolve this TLD + err = ErrUnknownTLD return } // continue with resolution relative to a zone. - return gns.ResolveRelative(labels[1:], pkey, kind, mode) + return gns.ResolveRelative(labels[1:], pkey, kind, mode, depth) } // Resolve relative path (to a given zone) recursively by processing simple // (PKEY,Label) lookups in sequence and handle intermediate GNS record types -func (gns *GNSModule) ResolveRelative(labels []string, pkey *ed25519.PublicKey, kind RRTypeList, mode int) (set *GNSRecordSet, err error) { +func (gns *GNSModule) ResolveRelative(labels []string, pkey *ed25519.PublicKey, kind RRTypeList, mode int, depth int) (set *message.GNSRecordSet, err error) { // Process all names in sequence var ( records []*message.GNSResourceRecord // final resource records from resolution @@ -150,15 +161,25 @@ func (gns *GNSModule) ResolveRelative(labels []string, pkey *ed25519.PublicKey, logger.Printf(logger.DBG, "[gns] ResolveRelative '%s' in '%s'\n", labels[0], util.EncodeBinaryToString(pkey.Bytes())) // resolve next level - var block *GNSBlock - if block, err = gns.Lookup(pkey, labels[0], mode == enums.GNS_LO_DEFAULT); err != nil { + var block *message.GNSBlock + if block, err = gns.Lookup(pkey, labels[0], mode); err != nil { // failed to resolve name return } // set new mode after processing right-most label in LOCAL_MASTER mode if mode == enums.GNS_LO_LOCAL_MASTER { + // if we have no results at this point, return NXDOMAIN + if block == nil { + // return record set with no entries as signal for NXDOMAIN + set = message.NewGNSRecordSet() + return + } mode = enums.GNS_LO_DEFAULT } + // signal NO_DATA if no block is found + if block == nil { + return + } // post-process block by inspecting contained resource records for // special GNS types if records, err = block.Records(); err != nil { @@ -204,7 +225,7 @@ func (gns *GNSModule) ResolveRelative(labels []string, pkey *ed25519.PublicKey, lbls += "." } fqdn := lbls + inst.Query - if set, err = gns.ResolveDNS(fqdn, inst.Servers, kind, pkey); err != nil { + if set, err = gns.ResolveDNS(fqdn, inst.Servers, kind, pkey, depth); err != nil { logger.Println(logger.ERROR, "[gns] GNS2DNS resolution failed.") return } @@ -224,10 +245,10 @@ func (gns *GNSModule) ResolveRelative(labels []string, pkey *ed25519.PublicKey, inst := hdlr.(*CnameHandler) // if we are at the end of the path and the requested type // includes GNS_TYPE_DNS_CNAME, the records are returned... - if len(labels) == 1 && kind.HasType(enums.GNS_TYPE_DNS_CNAME) { + if len(labels) == 1 && kind.HasType(enums.GNS_TYPE_DNS_CNAME) && !kind.IsAny() { break } - if set, err = gns.ResolveUnknown(inst.name, pkey, kind); err != nil { + if set, err = gns.ResolveUnknown(inst.name, labels, pkey, kind, depth+1); err != nil { logger.Println(logger.ERROR, "[gns] CNAME resolution failed.") return } @@ -238,7 +259,7 @@ func (gns *GNSModule) ResolveRelative(labels []string, pkey *ed25519.PublicKey, } // Assemble resulting resource record set by filtering for requested types. // Records might get transformed by active block handlers. - set = NewGNSRecordSet() + set = message.NewGNSRecordSet() for _, rec := range records { // is this the record type we are looking for? if kind.HasType(int(rec.Type)) { @@ -267,19 +288,22 @@ func (gns *GNSModule) ResolveRelative(labels []string, pkey *ed25519.PublicKey, // relative to the zone PKEY. If the name is an absolute GNS name (ending in // a PKEY TLD), it is also resolved with GNS. All other names are resolved // via DNS queries. -func (gns *GNSModule) ResolveUnknown(name string, pkey *ed25519.PublicKey, kind RRTypeList) (set *GNSRecordSet, err error) { +func (gns *GNSModule) ResolveUnknown(name string, labels []string, pkey *ed25519.PublicKey, kind RRTypeList, depth int) (set *message.GNSRecordSet, err error) { // relative GNS-based server name? if strings.HasSuffix(name, ".+") { // resolve server name relative to current zone name = strings.TrimSuffix(name, ".+") - if set, err = gns.Resolve(name, pkey, kind, enums.GNS_LO_DEFAULT); err != nil { + for _, label := range util.ReverseStringList(labels) { + name += "." + label + } + if set, err = gns.Resolve(name, pkey, kind, enums.GNS_LO_DEFAULT, depth+1); err != nil { return } } else { // check for absolute GNS name (with PKEY as TLD) if zk := gns.GetZoneKey(name); zk != nil { // resolve absolute GNS name (name ends in a PKEY) - if set, err = gns.Resolve(util.StripPathRight(name), zk, kind, enums.GNS_LO_DEFAULT); err != nil { + if set, err = gns.Resolve(util.StripPathRight(name), zk, kind, enums.GNS_LO_DEFAULT, depth+1); err != nil { return } } else { @@ -306,7 +330,7 @@ func (gns *GNSModule) GetZoneKey(path string) *ed25519.PublicKey { } // Lookup name in GNS. -func (gns *GNSModule) Lookup(pkey *ed25519.PublicKey, label string, remote bool) (block *GNSBlock, err error) { +func (gns *GNSModule) Lookup(pkey *ed25519.PublicKey, label string, mode int) (block *message.GNSBlock, err error) { // create query (lookup key) query := NewQuery(pkey, label) @@ -318,7 +342,7 @@ func (gns *GNSModule) Lookup(pkey *ed25519.PublicKey, label string, remote bool) return } if block == nil { - if remote { + if mode == enums.GNS_LO_DEFAULT { // get the block from a remote lookup if block, err = gns.LookupRemote(query); err != nil || block == nil { if err != nil { @@ -326,15 +350,12 @@ func (gns *GNSModule) Lookup(pkey *ed25519.PublicKey, label string, remote bool) block = nil } else { logger.Println(logger.DBG, "[gns] remote Lookup: no block found") - err = fmt.Errorf("No block found") } // lookup fails completely -- no result return } // store RRs from remote locally. - gns.StoreLocal(query, block) - } else { - err = fmt.Errorf("No block found") + gns.StoreLocal(block) } } return diff --git a/src/gnunet/service/gns/service.go b/src/gnunet/service/gns/service.go @@ -1,8 +1,28 @@ +// This file is part of gnunet-go, a GNUnet-implementation in Golang. +// Copyright (C) 2019, 2020 Bernd Fix >Y< +// +// gnunet-go is free software: you can redistribute it and/or modify it +// under the terms of the GNU Affero General Public License as published +// by the Free Software Foundation, either version 3 of the License, +// or (at your option) any later version. +// +// gnunet-go is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// +// SPDX-License-Identifier: AGPL3.0-or-later + package gns import ( "encoding/hex" + "fmt" "io" + "sync" "gnunet/config" "gnunet/crypto" @@ -17,6 +37,13 @@ import ( "github.com/bfix/gospel/logger" ) +// Error codes +var ( + ErrInvalidID = fmt.Errorf("Invalid/unassociated ID") + ErrBlockExpired = fmt.Errorf("Block expired") + ErrInvalidResponseType = fmt.Errorf("Invald response type") +) + //---------------------------------------------------------------------- // "GNUnet Name System" service implementation //---------------------------------------------------------------------- @@ -33,7 +60,6 @@ func NewGNSService() service.Service { inst.LookupLocal = inst.LookupNamecache inst.StoreLocal = inst.StoreNamecache inst.LookupRemote = inst.LookupDHT - inst.GetLocalZone = inst.GetPrivateZone return inst } @@ -48,7 +74,9 @@ func (s *GNSService) Stop() error { } // Serve a client channel. -func (s *GNSService) ServeClient(mc *transport.MsgChannel) { +func (s *GNSService) ServeClient(wg *sync.WaitGroup, mc *transport.MsgChannel) { + defer wg.Done() +loop: for { // receive next message from client msg, err := mc.Receive() @@ -58,7 +86,7 @@ func (s *GNSService) ServeClient(mc *transport.MsgChannel) { } else { logger.Printf(logger.ERROR, "[gns] Message-receive failed: %s\n", err.Error()) } - break + break loop } logger.Printf(logger.INFO, "[gns] Received msg: %v\n", msg) @@ -74,57 +102,58 @@ func (s *GNSService) ServeClient(mc *transport.MsgChannel) { resp = respX // perform lookup on block (locally and remote) - // TODO: run code in a go routine concurrently (would need - // access to the message channel to send responses) - pkey := ed25519.NewPublicKeyFromBytes(m.Zone) - label := m.GetName() - kind := NewRRTypeList(int(m.Type)) - recset, err := s.Resolve(label, pkey, kind, int(m.Options)) - if err != nil { - logger.Printf(logger.ERROR, "[gns] Failed to lookup block: %s\n", err.Error()) - break - } - // handle records - if recset != nil { - logger.Printf(logger.DBG, "[gns] Received record set with %d entries\n", recset.Count) - - // get records from block - if recset.Count == 0 { - logger.Println(logger.WARN, "[gns] No records in block") - break + wg.Add(1) + go func() { + defer wg.Done() + + pkey := ed25519.NewPublicKeyFromBytes(m.Zone) + label := m.GetName() + kind := NewRRTypeList(int(m.Type)) + recset, err := s.Resolve(label, pkey, kind, int(m.Options), 0) + if err != nil { + logger.Printf(logger.ERROR, "[gns] Failed to lookup block: %s\n", err.Error()) + return } - // process records - for i, rec := range recset.Records { - logger.Printf(logger.DBG, "[gns] Record #%d: %v\n", i, rec) - - // is this the record type we are looking for? - if rec.Type == m.Type || int(m.Type) == enums.GNS_TYPE_ANY { - // add it to the response message - respX.AddRecord(rec) + // handle records + if recset != nil { + logger.Printf(logger.DBG, "[gns] Received record set with %d entries\n", recset.Count) + + // get records from block + if recset.Count == 0 { + logger.Println(logger.WARN, "[gns] No records in block") + return + } + // process records + for i, rec := range recset.Records { + logger.Printf(logger.DBG, "[gns] Record #%d: %v\n", i, rec) + + // is this the record type we are looking for? + if rec.Type == m.Type || int(m.Type) == enums.GNS_TYPE_ANY { + // add it to the response message + respX.AddRecord(rec) + } } } - } + // send response + if err := mc.Send(resp); err != nil { + logger.Printf(logger.ERROR, "[gns] Failed to send response: %s\n", err.Error()) + } + }() default: //---------------------------------------------------------- // UNKNOWN message type received //---------------------------------------------------------- logger.Printf(logger.ERROR, "[gns] Unhandled message of type (%d)\n", msg.Header().MsgType) - continue - } - - // send response - if err := mc.Send(resp); err != nil { - logger.Printf(logger.ERROR, "[gns] Failed to send response: %s\n", err.Error()) + break loop } - } // close client connection mc.Close() } // LookupNamecache -func (s *GNSService) LookupNamecache(query *Query) (block *GNSBlock, err error) { +func (s *GNSService) LookupNamecache(query *Query) (block *message.GNSBlock, err error) { logger.Printf(logger.DBG, "[gns] LookupNamecache(%s)...\n", hex.EncodeToString(query.Key.Bits)) // assemble Namecache request @@ -145,6 +174,7 @@ func (s *GNSService) LookupNamecache(query *Query) (block *GNSBlock, err error) // check for matching IDs if m.Id != req.Id { logger.Println(logger.ERROR, "[gns] Got response for unknown ID") + err = ErrInvalidID break } // check if block was found @@ -155,14 +185,15 @@ func (s *GNSService) LookupNamecache(query *Query) (block *GNSBlock, err error) // check if record has expired if m.Expire.Expired() { logger.Printf(logger.ERROR, "[gns] block expired at %s\n", m.Expire) + err = ErrBlockExpired break } // assemble GNSBlock from message - block = new(GNSBlock) + block = new(message.GNSBlock) block.Signature = m.Signature block.DerivedKey = m.DerivedKey - sb := new(SignedBlockData) + sb := new(message.SignedBlockData) sb.Purpose = new(crypto.SignaturePurpose) sb.Purpose.Purpose = enums.SIG_GNS_RECORD_SIGN sb.Purpose.Size = uint32(16 + len(m.EncData)) @@ -177,18 +208,51 @@ func (s *GNSService) LookupNamecache(query *Query) (block *GNSBlock, err error) if err = block.Decrypt(query.Zone, query.Label); err != nil { break } + default: + logger.Printf(logger.ERROR, "[gns] Got invalid response type (%d)\n", m.Header().MsgType) + err = ErrInvalidResponseType } return } // StoreNamecache -func (s *GNSService) StoreNamecache(query *Query, block *GNSBlock) error { - logger.Println(logger.WARN, "[gns] StoreNamecache() not implemented yet!") - return nil +func (s *GNSService) StoreNamecache(block *message.GNSBlock) (err error) { + logger.Println(logger.DBG, "[gns] StoreNamecache()...") + + // assemble Namecache request + req := message.NewNamecacheCacheMsg(block) + req.Id = uint32(util.NextID()) + + // get response from Namecache service + var resp message.Message + if resp, err = service.ServiceRequestResponse("gns", "Namecache", config.Cfg.Namecache.Endpoint, req); err != nil { + return + } + + // handle message depending on its type + logger.Println(logger.DBG, "[gns] Handling response from Namecache service") + switch m := resp.(type) { + case *message.NamecacheCacheResponseMsg: + // check for matching IDs + if m.Id != req.Id { + logger.Println(logger.ERROR, "[gns] Got response for unknown ID") + err = ErrInvalidID + break + } + // check result + if m.Result == 0 { + return nil + } + return fmt.Errorf("Failed with rc=%d", m.Result) + default: + logger.Printf(logger.ERROR, "[gns] Got invalid response type (%d)\n", m.Header().MsgType) + err = ErrInvalidResponseType + } + return } // LookupDHT -func (s *GNSService) LookupDHT(query *Query) (block *GNSBlock, err error) { +func (s *GNSService) LookupDHT(query *Query) (block *message.GNSBlock, err error) { logger.Printf(logger.DBG, "[gns] LookupDHT(%s)...\n", hex.EncodeToString(query.Key.Bits)) // assemble DHT request @@ -231,7 +295,7 @@ func (s *GNSService) LookupDHT(query *Query) (block *GNSBlock, err error) { } // get GNSBlock from message - block = NewGNSBlock() + block = message.NewGNSBlock() if err = data.Unmarshal(block, m.Data); err != nil { logger.Printf(logger.ERROR, "[gns] can't read GNS block: %s\n", err.Error()) break @@ -246,14 +310,9 @@ func (s *GNSService) LookupDHT(query *Query) (block *GNSBlock, err error) { // we got a result from DHT that was not in the namecache, // so store it there now. - if err = s.StoreNamecache(query, block); err != nil { + if err = s.StoreNamecache(block); err != nil { logger.Printf(logger.ERROR, "[gns] can't store block in Namecache: %s\n", err.Error()) } } return } - -// GetPrivateZone -func (s *GNSService) GetPrivateZone(name string) (*ed25519.PublicKey, error) { - return nil, nil -} diff --git a/src/gnunet/service/namecache/module.go b/src/gnunet/service/namecache/module.go @@ -1,6 +1,25 @@ +// This file is part of gnunet-go, a GNUnet-implementation in Golang. +// Copyright (C) 2019, 2020 Bernd Fix >Y< +// +// gnunet-go is free software: you can redistribute it and/or modify it +// under the terms of the GNU Affero General Public License as published +// by the Free Software Foundation, either version 3 of the License, +// or (at your option) any later version. +// +// gnunet-go is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// +// SPDX-License-Identifier: AGPL3.0-or-later + package namecache import ( + "gnunet/message" "gnunet/service/gns" ) @@ -16,10 +35,10 @@ import ( type NamecacheModule struct { } -func (nc *NamecacheModule) Get(query *gns.Query) (*gns.GNSBlock, error) { +func (nc *NamecacheModule) Get(query *gns.Query) (*message.GNSBlock, error) { return nil, nil } -func (nc *NamecacheModule) Put(query *gns.Query, block *gns.GNSBlock) error { +func (nc *NamecacheModule) Put(block *message.GNSBlock) error { return nil } diff --git a/src/gnunet/service/service.go b/src/gnunet/service/service.go @@ -1,7 +1,26 @@ +// This file is part of gnunet-go, a GNUnet-implementation in Golang. +// Copyright (C) 2019, 2020 Bernd Fix >Y< +// +// gnunet-go is free software: you can redistribute it and/or modify it +// under the terms of the GNU Affero General Public License as published +// by the Free Software Foundation, either version 3 of the License, +// or (at your option) any later version. +// +// gnunet-go is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// +// SPDX-License-Identifier: AGPL3.0-or-later + package service import ( "fmt" + "sync" "gnunet/transport" @@ -14,7 +33,7 @@ import ( // Channel semantics in the specification string. type Service interface { Start(spec string) error - ServeClient(ch *transport.MsgChannel) + ServeClient(wg *sync.WaitGroup, ch *transport.MsgChannel) Stop() error } @@ -24,6 +43,7 @@ type ServiceImpl struct { hdlr chan transport.Channel ctrl chan bool srvc transport.ChannelServer + wg *sync.WaitGroup name string running bool } @@ -35,6 +55,7 @@ func NewServiceImpl(name string, srv Service) *ServiceImpl { hdlr: make(chan transport.Channel), ctrl: make(chan bool), srvc: nil, + wg: new(sync.WaitGroup), name: name, running: false, } @@ -56,7 +77,9 @@ func (si *ServiceImpl) Start(spec string) (err error) { si.running = true // handle clients + si.wg.Add(1) go func() { + defer si.wg.Done() loop: for si.running { select { @@ -68,7 +91,8 @@ func (si *ServiceImpl) Start(spec string) (err error) { switch ch := in.(type) { case transport.Channel: logger.Printf(logger.INFO, "[%s] Client connected.\n", si.name) - go si.impl.ServeClient(transport.NewMsgChannel(ch)) + si.wg.Add(1) + go si.impl.ServeClient(si.wg, transport.NewMsgChannel(ch)) } case <-si.ctrl: break loop @@ -92,5 +116,7 @@ func (si *ServiceImpl) Stop() error { si.ctrl <- true logger.Printf(logger.INFO, "[%s] Service terminating.\n", si.name) - return si.impl.Stop() + err := si.impl.Stop() + si.wg.Wait() + return err } diff --git a/src/gnunet/transport/channel.go b/src/gnunet/transport/channel.go @@ -1,14 +1,35 @@ +// This file is part of gnunet-go, a GNUnet-implementation in Golang. +// Copyright (C) 2019, 2020 Bernd Fix >Y< +// +// gnunet-go is free software: you can redistribute it and/or modify it +// under the terms of the GNU Affero General Public License as published +// by the Free Software Foundation, either version 3 of the License, +// or (at your option) any later version. +// +// gnunet-go is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// +// SPDX-License-Identifier: AGPL3.0-or-later + package transport import ( "encoding/hex" "errors" "fmt" + "path" "strings" + "gnunet/message" + "gnunet/util" + "github.com/bfix/gospel/data" "github.com/bfix/gospel/logger" - "gnunet/message" ) // Error codes @@ -79,12 +100,19 @@ var channelServerImpl = map[string]ChannelServerFactory{ } // NewChannelServer -func NewChannelServer(spec string, hdlr chan<- Channel) (ChannelServer, error) { +func NewChannelServer(spec string, hdlr chan<- Channel) (cs ChannelServer, err error) { parts := strings.Split(spec, "+") + if fac, ok := channelServerImpl[parts[0]]; ok { - inst := fac() - err := inst.Open(spec, hdlr) - return inst, err + // check if the basedir for the spec exists... + if err = util.EnforceDirExists(path.Dir(parts[1])); err != nil { + return + } + // instantiate server implementation + cs = fac() + // create the domain socket and listen to it. + err = cs.Open(spec, hdlr) + return } return nil, ErrChannelNotImplemented } diff --git a/src/gnunet/transport/channel_netw.go b/src/gnunet/transport/channel_netw.go @@ -1,3 +1,21 @@ +// This file is part of gnunet-go, a GNUnet-implementation in Golang. +// Copyright (C) 2019, 2020 Bernd Fix >Y< +// +// gnunet-go is free software: you can redistribute it and/or modify it +// under the terms of the GNU Affero General Public License as published +// by the Free Software Foundation, either version 3 of the License, +// or (at your option) any later version. +// +// gnunet-go is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// +// SPDX-License-Identifier: AGPL3.0-or-later + package transport import ( diff --git a/src/gnunet/transport/channel_test.go b/src/gnunet/transport/channel_test.go @@ -1,3 +1,21 @@ +// This file is part of gnunet-go, a GNUnet-implementation in Golang. +// Copyright (C) 2019, 2020 Bernd Fix >Y< +// +// gnunet-go is free software: you can redistribute it and/or modify it +// under the terms of the GNU Affero General Public License as published +// by the Free Software Foundation, either version 3 of the License, +// or (at your option) any later version. +// +// gnunet-go is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// +// SPDX-License-Identifier: AGPL3.0-or-later + package transport import ( diff --git a/src/gnunet/transport/connection.go b/src/gnunet/transport/connection.go @@ -1,3 +1,21 @@ +// This file is part of gnunet-go, a GNUnet-implementation in Golang. +// Copyright (C) 2019, 2020 Bernd Fix >Y< +// +// gnunet-go is free software: you can redistribute it and/or modify it +// under the terms of the GNU Affero General Public License as published +// by the Free Software Foundation, either version 3 of the License, +// or (at your option) any later version. +// +// gnunet-go is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// +// SPDX-License-Identifier: AGPL3.0-or-later + package transport import ( diff --git a/src/gnunet/transport/session.go b/src/gnunet/transport/session.go @@ -1,3 +1,21 @@ +// This file is part of gnunet-go, a GNUnet-implementation in Golang. +// Copyright (C) 2019, 2020 Bernd Fix >Y< +// +// gnunet-go is free software: you can redistribute it and/or modify it +// under the terms of the GNU Affero General Public License as published +// by the Free Software Foundation, either version 3 of the License, +// or (at your option) any later version. +// +// gnunet-go is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// +// SPDX-License-Identifier: AGPL3.0-or-later + package transport // Session states diff --git a/src/gnunet/util/address.go b/src/gnunet/util/address.go @@ -1,3 +1,21 @@ +// This file is part of gnunet-go, a GNUnet-implementation in Golang. +// Copyright (C) 2019, 2020 Bernd Fix >Y< +// +// gnunet-go is free software: you can redistribute it and/or modify it +// under the terms of the GNU Affero General Public License as published +// by the Free Software Foundation, either version 3 of the License, +// or (at your option) any later version. +// +// gnunet-go is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// +// SPDX-License-Identifier: AGPL3.0-or-later + package util import ( diff --git a/src/gnunet/util/array.go b/src/gnunet/util/array.go @@ -1,3 +1,21 @@ +// This file is part of gnunet-go, a GNUnet-implementation in Golang. +// Copyright (C) 2019, 2020 Bernd Fix >Y< +// +// gnunet-go is free software: you can redistribute it and/or modify it +// under the terms of the GNU Affero General Public License as published +// by the Free Software Foundation, either version 3 of the License, +// or (at your option) any later version. +// +// gnunet-go is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// +// SPDX-License-Identifier: AGPL3.0-or-later + package util import ( diff --git a/src/gnunet/util/base32.go b/src/gnunet/util/base32.go @@ -1,3 +1,21 @@ +// This file is part of gnunet-go, a GNUnet-implementation in Golang. +// Copyright (C) 2019, 2020 Bernd Fix >Y< +// +// gnunet-go is free software: you can redistribute it and/or modify it +// under the terms of the GNU Affero General Public License as published +// by the Free Software Foundation, either version 3 of the License, +// or (at your option) any later version. +// +// gnunet-go is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// +// SPDX-License-Identifier: AGPL3.0-or-later + package util import ( diff --git a/src/gnunet/util/base32_test.go b/src/gnunet/util/base32_test.go @@ -1,3 +1,21 @@ +// This file is part of gnunet-go, a GNUnet-implementation in Golang. +// Copyright (C) 2019, 2020 Bernd Fix >Y< +// +// gnunet-go is free software: you can redistribute it and/or modify it +// under the terms of the GNU Affero General Public License as published +// by the Free Software Foundation, either version 3 of the License, +// or (at your option) any later version. +// +// gnunet-go is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// +// SPDX-License-Identifier: AGPL3.0-or-later + package util import ( diff --git a/src/gnunet/util/format.go b/src/gnunet/util/format.go @@ -1,3 +1,21 @@ +// This file is part of gnunet-go, a GNUnet-implementation in Golang. +// Copyright (C) 2019, 2020 Bernd Fix >Y< +// +// gnunet-go is free software: you can redistribute it and/or modify it +// under the terms of the GNU Affero General Public License as published +// by the Free Software Foundation, either version 3 of the License, +// or (at your option) any later version. +// +// gnunet-go is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// +// SPDX-License-Identifier: AGPL3.0-or-later + package util import ( diff --git a/src/gnunet/util/fs.go b/src/gnunet/util/fs.go @@ -0,0 +1,43 @@ +// This file is part of gnunet-go, a GNUnet-implementation in Golang. +// Copyright (C) 2019, 2020 Bernd Fix >Y< +// +// gnunet-go is free software: you can redistribute it and/or modify it +// under the terms of the GNU Affero General Public License as published +// by the Free Software Foundation, either version 3 of the License, +// or (at your option) any later version. +// +// gnunet-go is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// +// SPDX-License-Identifier: AGPL3.0-or-later + +package util + +import ( + "fmt" + "os" + + "github.com/bfix/gospel/logger" +) + +// EnforceDirExists make sure that the path +func EnforceDirExists(path string) error { + logger.Printf(logger.DBG, "[util] Checking directory '%s'...\n", path) + fi, err := os.Lstat(path) + if err != nil { + if os.IsNotExist(err) { + logger.Printf(logger.DBG, "[util] Creating directory '%s'...\n", path) + return os.Mkdir(path, 0770) + } + return err + } + if !fi.IsDir() { + return fmt.Errorf("Not a directory (%s)", path) + } + return nil +} diff --git a/src/gnunet/util/id.go b/src/gnunet/util/id.go @@ -1,3 +1,21 @@ +// This file is part of gnunet-go, a GNUnet-implementation in Golang. +// Copyright (C) 2019, 2020 Bernd Fix >Y< +// +// gnunet-go is free software: you can redistribute it and/or modify it +// under the terms of the GNU Affero General Public License as published +// by the Free Software Foundation, either version 3 of the License, +// or (at your option) any later version. +// +// gnunet-go is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// +// SPDX-License-Identifier: AGPL3.0-or-later + package util var ( diff --git a/src/gnunet/util/misc.go b/src/gnunet/util/misc.go @@ -1,3 +1,21 @@ +// This file is part of gnunet-go, a GNUnet-implementation in Golang. +// Copyright (C) 2019, 2020 Bernd Fix >Y< +// +// gnunet-go is free software: you can redistribute it and/or modify it +// under the terms of the GNU Affero General Public License as published +// by the Free Software Foundation, either version 3 of the License, +// or (at your option) any later version. +// +// gnunet-go is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// +// SPDX-License-Identifier: AGPL3.0-or-later + package util import ( diff --git a/src/gnunet/util/peer_id.go b/src/gnunet/util/peer_id.go @@ -1,3 +1,21 @@ +// This file is part of gnunet-go, a GNUnet-implementation in Golang. +// Copyright (C) 2019, 2020 Bernd Fix >Y< +// +// gnunet-go is free software: you can redistribute it and/or modify it +// under the terms of the GNU Affero General Public License as published +// by the Free Software Foundation, either version 3 of the License, +// or (at your option) any later version. +// +// gnunet-go is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// +// SPDX-License-Identifier: AGPL3.0-or-later + package util // PeerID is the 32-byte binary representation od a Ed25519 key diff --git a/src/gnunet/util/rnd.go b/src/gnunet/util/rnd.go @@ -1,3 +1,21 @@ +// This file is part of gnunet-go, a GNUnet-implementation in Golang. +// Copyright (C) 2019, 2020 Bernd Fix >Y< +// +// gnunet-go is free software: you can redistribute it and/or modify it +// under the terms of the GNU Affero General Public License as published +// by the Free Software Foundation, either version 3 of the License, +// or (at your option) any later version. +// +// gnunet-go is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// +// SPDX-License-Identifier: AGPL3.0-or-later + package util import ( diff --git a/src/gnunet/util/time.go b/src/gnunet/util/time.go @@ -1,3 +1,21 @@ +// This file is part of gnunet-go, a GNUnet-implementation in Golang. +// Copyright (C) 2019, 2020 Bernd Fix >Y< +// +// gnunet-go is free software: you can redistribute it and/or modify it +// under the terms of the GNU Affero General Public License as published +// by the Free Software Foundation, either version 3 of the License, +// or (at your option) any later version. +// +// gnunet-go is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// +// SPDX-License-Identifier: AGPL3.0-or-later + package util import (