main.go (3354B)
1 // This file is part of taldir, the Taler Directory implementation. 2 // Copyright (C) 2022 Martin Schanzenbach 3 // 4 // Taldir is free software: you can redistribute it and/or modify it 5 // under the terms of the GNU Affero General Public License as published 6 // by the Free Software Foundation, either version 3 of the License, 7 // or (at your option) any later version. 8 // 9 // Taldir is distributed in the hope that it will be useful, but 10 // WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 // Affero General Public License for more details. 13 // 14 // You should have received a copy of the GNU Affero General Public License 15 // along with this program. If not, see <http://www.gnu.org/licenses/>. 16 // 17 // SPDX-License-Identifier: AGPL3.0-or-later 18 19 package main 20 21 import ( 22 "crypto/sha512" 23 "encoding/binary" 24 "flag" 25 "fmt" 26 "log" 27 "net/url" 28 "os" 29 "path/filepath" 30 31 "gopkg.in/ini.v1" 32 "rsc.io/getopt" 33 "taler.net/taldir/internal/util" 34 ) 35 36 var ( 37 version string 38 ) 39 40 // Hashes the alias with its type in a prefix-free fashion 41 // SHA512(len(atype||alias)||atype||alias) 42 func hashAlias(atype string, alias string) []byte { 43 h := sha512.New() 44 b := make([]byte, 4) 45 binary.BigEndian.PutUint32(b, uint32(len(atype)+len(alias))) 46 h.Write(b) 47 h.Write([]byte(atype)) 48 h.Write([]byte(alias)) 49 return h.Sum(nil) 50 } 51 52 // Generates a link from a challenge and alias 53 func generateLink(host string, alias string, atype string, challenge string) string { 54 hAlias := hashAlias(atype, alias) 55 hAliasEnc := util.Base32CrockfordEncode(hAlias) 56 return host + "/register/" + url.QueryEscape(hAliasEnc) + "/" + url.QueryEscape(challenge) + "?alias=" + url.QueryEscape(alias) 57 } 58 59 func main() { 60 var solveFlag = flag.Bool("s", false, "Provide a solution for the challenge/pubkey") 61 getopt.Alias("s", "solve") 62 var linkFlag = flag.Bool("l", false, "Provide a link for activation") 63 getopt.Alias("l", "link") 64 var challengeFlag = flag.String("c", "", "Activation challenge") 65 getopt.Alias("c", "challenge") 66 var pubkeyFlag = flag.String("p", "", "Public key") 67 getopt.Alias("p", "public-key") 68 var aliasFlag = flag.String("a", "", "Alias") 69 getopt.Alias("a", "alias") 70 var atypeFlag = flag.String("t", "", "Alias type") 71 getopt.Alias("t", "alias-type") 72 var versionFlag = flag.Bool("v", false, "Print version") 73 getopt.Alias("v", "version") 74 flag.Parse() 75 cfgfile := "taldir.conf" 76 _cfg, err := ini.LooseLoad(cfgfile) 77 if err != nil { 78 log.Fatalf("Failed to read config: %v", err) 79 os.Exit(1) 80 } 81 if *versionFlag { 82 fullName, err := os.Executable() 83 if err != nil { 84 log.Panic(err) 85 } 86 fmt.Printf("%s %s", filepath.Base(fullName), version) 87 return 88 } 89 host := _cfg.Section("directory").Key("base_url").MustString("http://localhost") 90 if *solveFlag { 91 if len(*challengeFlag) == 0 || len(*pubkeyFlag) == 0 { 92 fmt.Println("You need to provide an activation challenge and a public key to generate a solution") 93 os.Exit(1) 94 } 95 fmt.Println(util.GenerateSolution(*pubkeyFlag, *challengeFlag)) 96 os.Exit(0) 97 } 98 if *linkFlag { 99 if len(*challengeFlag) == 0 || len(*aliasFlag) == 0 || len(*atypeFlag) == 0 { 100 fmt.Println("You need to provide an activation challenge and an alias to generate a link") 101 os.Exit(1) 102 } 103 fmt.Println(generateLink(host, *aliasFlag, *atypeFlag, *challengeFlag)) 104 os.Exit(0) 105 } 106 }