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