]> Cypherpunks.ru repositories - nncp.git/blob - src/cmd/nncp-cfgnew/main.go
Update dependencies
[nncp.git] / src / cmd / nncp-cfgnew / main.go
1 /*
2 NNCP -- Node to Node copy, utilities for store-and-forward data exchange
3 Copyright (C) 2016-2023 Sergey Matveev <stargrave@stargrave.org>
4
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, version 3 of the License.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 */
17
18 // Generate new NNCP node keys and configuration file
19 package main
20
21 import (
22         "crypto/ed25519"
23         "crypto/rand"
24         "encoding/hex"
25         "encoding/json"
26         "flag"
27         "fmt"
28         "log"
29         "os"
30
31         "github.com/hjson/hjson-go/v4"
32         "golang.org/x/crypto/blake2b"
33         "golang.org/x/crypto/nacl/box"
34
35         "go.cypherpunks.ru/nncp/v8"
36 )
37
38 func usage() {
39         fmt.Fprintln(os.Stderr, "nncp-cfgnew -- generate new configuration and keys\nOptions:")
40         flag.PrintDefaults()
41 }
42
43 func main() {
44         var (
45                 areaName   = flag.String("area", "", "Generate area's keypairs")
46                 yggdrasil  = flag.Bool("yggdrasil", false, "Generate Yggdrasil keypair")
47                 noComments = flag.Bool("nocomments", false, "Do not include descriptive comments")
48                 version    = flag.Bool("version", false, "Print version information")
49                 warranty   = flag.Bool("warranty", false, "Print warranty information")
50         )
51         log.SetFlags(log.Lshortfile)
52         flag.Usage = usage
53         flag.Parse()
54         if *warranty {
55                 fmt.Println(nncp.Warranty)
56                 return
57         }
58         if *version {
59                 fmt.Println(nncp.VersionGet())
60                 return
61         }
62
63         if *yggdrasil {
64                 pub, prv, err := ed25519.GenerateKey(rand.Reader)
65                 if err != nil {
66                         log.Fatalln(err)
67                 }
68                 fmt.Println("Public:", hex.EncodeToString(pub))
69                 fmt.Println("Private:", hex.EncodeToString(prv))
70                 return
71         }
72
73         if *areaName != "" {
74                 pub, prv, err := box.GenerateKey(rand.Reader)
75                 if err != nil {
76                         log.Fatalln(err)
77                 }
78                 areaId := nncp.AreaId(blake2b.Sum256(pub[:]))
79                 var cfgRaw string
80                 if *noComments {
81                         cfgRaw = fmt.Sprintf(`areas: {
82   %s: {
83     id: %s
84     # KEEP AWAY keypair from the nodes you want only participate in multicast
85     pub: %s
86     prv: %s
87   }
88 }`,
89                                 *areaName,
90                                 areaId.String(),
91                                 nncp.Base32Codec.EncodeToString(pub[:]),
92                                 nncp.Base32Codec.EncodeToString(prv[:]),
93                         )
94                 } else {
95                         cfgRaw = fmt.Sprintf(`areas: {
96   %s: {
97     id: %s
98
99     # KEEP AWAY keypair from the nodes you want only participate in multicast
100     pub: %s
101     prv: %s
102
103     # List of subscribers you should multicast area messages to
104     # subs: ["alice"]
105
106     # Allow incoming files (from the area) saving in that directory
107     # incoming: /home/areas/%s/incoming
108
109     # Allow incoming area commands execution
110     # exec: {sendmail: ["%s"]}
111
112     # Allow unknown sender's message tossing (relaying will be made anyway)
113     # allow-unknown: true
114   }
115 }`,
116                                 *areaName,
117                                 areaId.String(),
118                                 nncp.Base32Codec.EncodeToString(pub[:]),
119                                 nncp.Base32Codec.EncodeToString(prv[:]),
120                                 *areaName,
121                                 nncp.DefaultSendmailPath,
122                         )
123                 }
124                 var cfgGeneral map[string]interface{}
125                 if err = hjson.Unmarshal([]byte(cfgRaw), &cfgGeneral); err != nil {
126                         panic(err)
127                 }
128                 marshaled, err := json.Marshal(cfgGeneral)
129                 if err != nil {
130                         panic(err)
131                 }
132                 var areas map[string]nncp.AreaJSON
133                 if err = json.Unmarshal(marshaled, &areas); err != nil {
134                         panic(err)
135                 }
136                 fmt.Println(cfgRaw)
137                 return
138         }
139
140         nodeOur, err := nncp.NewNodeGenerate()
141         if err != nil {
142                 log.Fatalln(err)
143         }
144         var cfgRaw string
145         if *noComments {
146                 cfgRaw = fmt.Sprintf(`{
147   spool: %s
148   log: %s
149
150   self: {
151     # DO NOT show anyone your private keys!!!
152     id: %s
153     exchpub: %s
154     exchprv: %s
155     signpub: %s
156     signprv: %s
157     noiseprv: %s
158     noisepub: %s
159   }
160
161   neigh: {
162     self: {
163       id: %s
164       exchpub: %s
165       signpub: %s
166       noisepub: %s
167       exec: {sendmail: ["%s"]}
168     }
169   }
170 }`,
171                         nncp.DefaultSpoolPath,
172                         nncp.DefaultLogPath,
173                         nodeOur.Id.String(),
174                         nncp.Base32Codec.EncodeToString(nodeOur.ExchPub[:]),
175                         nncp.Base32Codec.EncodeToString(nodeOur.ExchPrv[:]),
176                         nncp.Base32Codec.EncodeToString(nodeOur.SignPub[:]),
177                         nncp.Base32Codec.EncodeToString(nodeOur.SignPrv[:]),
178                         nncp.Base32Codec.EncodeToString(nodeOur.NoisePrv[:]),
179                         nncp.Base32Codec.EncodeToString(nodeOur.NoisePub[:]),
180                         nodeOur.Id.String(),
181                         nncp.Base32Codec.EncodeToString(nodeOur.ExchPub[:]),
182                         nncp.Base32Codec.EncodeToString(nodeOur.SignPub[:]),
183                         nncp.Base32Codec.EncodeToString(nodeOur.NoisePub[:]),
184                         nncp.DefaultSendmailPath,
185                 )
186         } else {
187                 cfgRaw = fmt.Sprintf(`{
188   # Path to encrypted packets spool directory
189   spool: %s
190   # Path to log file
191   log: %s
192   # Enforce specified umask usage
193   # umask: "022"
194   # Omit progress showing by default
195   # noprogress: true
196   # Do not use hdr/ files
197   # nohdr: true
198
199   # MultiCast Discovery:
200   # List of interface regular expressions where to listen for MCD announcements
201   mcd-listen: [".*"]
202   # Interfaces regular expressions and intervals (in seconds) where to send
203   # MCD announcements
204   mcd-send: {.*: 10}
205
206   # Yggdrasil related aliases:
207   # yggdrasil-aliases: {
208   #   myprv: 60bb...27aa
209   #   bob-pub: 98de...ac19d
210   #   alice-endpoint: tcp://example.com:1234?key=689c...13fb
211   #   default-endpoints: tcp://[::1]:2345,alice-endpoint
212   # }
213
214   # Enable notification email sending
215   # notify: {
216   #   file: {
217   #     from: nncp@localhost
218   #     to: user+file@example.com
219   #   }
220   #   freq: {
221   #     from: nncp@localhost
222   #     to: user+freq@example.com
223   #   }
224   #   # Send some exec commands execution notifications
225   #   exec: {
226   #     # bob neighbour's "somehandle" notification
227   #     bob.somehandle: {
228   #       from: nncp+bob@localhost
229   #       to: user+somehandle@example.com
230   #     }
231   #     # Any neighboor's "anotherhandle"
232   #     *.anotherhandle: {
233   #       from: nncp@localhost
234   #       to: user+anotherhandle@example.com
235   #     }
236   #   }
237   # }
238
239   self: {
240     # DO NOT show anyone your private keys!!!
241     id: %s
242     exchpub: %s
243     exchprv: %s
244     signpub: %s
245     signprv: %s
246     noiseprv: %s
247     noisepub: %s
248   }
249
250   neigh: {
251     self: {
252       # You should give public keys below to your neighbours
253       id: %s
254       exchpub: %s
255       signpub: %s
256       noisepub: %s
257
258       exec: {
259         # Default self's sendmail command is used for email notifications sending
260         sendmail: ["%s"]
261       }
262     }
263
264     # Example neighbour, most of fields are optional
265     # alice: {
266     #   id: XJZBK...65IJQ
267     #   exchpub: MJACJ...FAI6A
268     #   signpub: T4AFC...N2FRQ
269     #   noisepub: UBM5K...VI42A
270     #
271     #   # He is allowed to send email
272     #   # exec: {sendmail: ["%s"]}
273     #
274     #   # Allow incoming files saving in that directory
275     #   # incoming: "/home/alice/incoming"
276     #
277     #   # Transitional nodes path
278     #   # via: ["bob", "eve"]
279     #
280     #   # Inactivity timeout when session with remote peer should be terminated
281     #   # onlinedeadline: 1800
282     #
283     #   # Maximal online session lifetime
284     #   # maxonlinetime: 3600
285     #
286     #   # If neither freq section, nor freq.path exist, then no freqing allowed
287     #   # freq: {
288     #   #   # Allow freqing from that directory
289     #   #   path: "/home/bob/pub"
290     #   #   # Send freqed files with chunks
291     #   #   # chunked: 1024
292     #   #   # Send freqed files with minumal chunk size
293     #   #   # minsize: 2048
294     #   #   # Maximal allowable freqing file size
295     #   #   # maxsize: 4096
296     #   # }
297     #
298     #   # Set maximal packets per second receive and transmit rates
299     #   # rxrate: 10
300     #   # txrate: 20
301     #
302     #   # Address aliases
303     #   # addrs: {
304     #   #   lan: "[fe80::1234%%igb0]:5400"
305     #   #   internet: alice.com:3389
306     #   # }
307     #
308     #   # Calls configuration
309     #   # calls: [
310     #   #   {
311     #   #     cron: "*/2 * * * *"
312     #   #     onlinedeadline: 1800
313     #   #     maxonlinetime: 1750
314     #   #     nice: PRIORITY+10
315     #   #     rxrate: 10
316     #   #     txrate: 20
317     #   #     xx: rx
318     #   #     addr: lan
319     #   #     when-tx-exists: true
320     #   #     nock: true
321     #   #     mcd-ignore: true
322     #   #
323     #   #     autotoss: false
324     #   #     autotoss-doseen: true
325     #   #     autotoss-nofile: true
326     #   #     autotoss-nofreq: true
327     #   #     autotoss-noexec: true
328     #   #     autotoss-notrns: true
329     #   #   }
330     #   # ]
331     # }
332   }
333 }`,
334                         nncp.DefaultSpoolPath,
335                         nncp.DefaultLogPath,
336                         nodeOur.Id.String(),
337                         nncp.Base32Codec.EncodeToString(nodeOur.ExchPub[:]),
338                         nncp.Base32Codec.EncodeToString(nodeOur.ExchPrv[:]),
339                         nncp.Base32Codec.EncodeToString(nodeOur.SignPub[:]),
340                         nncp.Base32Codec.EncodeToString(nodeOur.SignPrv[:]),
341                         nncp.Base32Codec.EncodeToString(nodeOur.NoisePrv[:]),
342                         nncp.Base32Codec.EncodeToString(nodeOur.NoisePub[:]),
343                         nodeOur.Id.String(),
344                         nncp.Base32Codec.EncodeToString(nodeOur.ExchPub[:]),
345                         nncp.Base32Codec.EncodeToString(nodeOur.SignPub[:]),
346                         nncp.Base32Codec.EncodeToString(nodeOur.NoisePub[:]),
347                         nncp.DefaultSendmailPath,
348                         nncp.DefaultSendmailPath,
349                 )
350         }
351         if _, err = nncp.CfgParse([]byte(cfgRaw)); err != nil {
352                 panic(err)
353         }
354         fmt.Println(cfgRaw)
355 }