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