github.com/divan/go-ethereum@v1.8.14-0.20180820134928-1de9ada4016d/cmd/swarm/access.go (about)

     1  // Copyright 2018 The go-ethereum Authors
     2  // This file is part of go-ethereum.
     3  //
     4  // go-ethereum 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, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // go-ethereum 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 go-ethereum. If not, see <http://www.gnu.org/licenses/>.
    16  package main
    17  
    18  import (
    19  	"crypto/rand"
    20  	"encoding/json"
    21  	"fmt"
    22  	"io"
    23  	"io/ioutil"
    24  	"strings"
    25  
    26  	"github.com/ethereum/go-ethereum/cmd/utils"
    27  	"github.com/ethereum/go-ethereum/swarm/api"
    28  	"github.com/ethereum/go-ethereum/swarm/api/client"
    29  	"gopkg.in/urfave/cli.v1"
    30  )
    31  
    32  var salt = make([]byte, 32)
    33  
    34  func init() {
    35  	if _, err := io.ReadFull(rand.Reader, salt); err != nil {
    36  		panic("reading from crypto/rand failed: " + err.Error())
    37  	}
    38  }
    39  
    40  func accessNewPass(ctx *cli.Context) {
    41  	args := ctx.Args()
    42  	if len(args) != 1 {
    43  		utils.Fatalf("Expected 1 argument - the ref")
    44  	}
    45  
    46  	var (
    47  		ae        *api.AccessEntry
    48  		accessKey []byte
    49  		err       error
    50  		ref       = args[0]
    51  		password  = getPassPhrase("", 0, makePasswordList(ctx))
    52  		dryRun    = ctx.Bool(SwarmDryRunFlag.Name)
    53  	)
    54  	accessKey, ae, err = api.DoPasswordNew(ctx, password, salt)
    55  	if err != nil {
    56  		utils.Fatalf("error getting session key: %v", err)
    57  	}
    58  	m, err := api.GenerateAccessControlManifest(ctx, ref, accessKey, ae)
    59  	if dryRun {
    60  		err = printManifests(m, nil)
    61  		if err != nil {
    62  			utils.Fatalf("had an error printing the manifests: %v", err)
    63  		}
    64  	} else {
    65  		utils.Fatalf("uploading manifests")
    66  		err = uploadManifests(ctx, m, nil)
    67  		if err != nil {
    68  			utils.Fatalf("had an error uploading the manifests: %v", err)
    69  		}
    70  	}
    71  }
    72  
    73  func accessNewPK(ctx *cli.Context) {
    74  	args := ctx.Args()
    75  	if len(args) != 1 {
    76  		utils.Fatalf("Expected 1 argument - the ref")
    77  	}
    78  
    79  	var (
    80  		ae               *api.AccessEntry
    81  		sessionKey       []byte
    82  		err              error
    83  		ref              = args[0]
    84  		privateKey       = getPrivKey(ctx)
    85  		granteePublicKey = ctx.String(SwarmAccessGrantKeyFlag.Name)
    86  		dryRun           = ctx.Bool(SwarmDryRunFlag.Name)
    87  	)
    88  	sessionKey, ae, err = api.DoPKNew(ctx, privateKey, granteePublicKey, salt)
    89  	if err != nil {
    90  		utils.Fatalf("error getting session key: %v", err)
    91  	}
    92  	m, err := api.GenerateAccessControlManifest(ctx, ref, sessionKey, ae)
    93  	if dryRun {
    94  		err = printManifests(m, nil)
    95  		if err != nil {
    96  			utils.Fatalf("had an error printing the manifests: %v", err)
    97  		}
    98  	} else {
    99  		err = uploadManifests(ctx, m, nil)
   100  		if err != nil {
   101  			utils.Fatalf("had an error uploading the manifests: %v", err)
   102  		}
   103  	}
   104  }
   105  
   106  func accessNewACT(ctx *cli.Context) {
   107  	args := ctx.Args()
   108  	if len(args) != 1 {
   109  		utils.Fatalf("Expected 1 argument - the ref")
   110  	}
   111  
   112  	var (
   113  		ae          *api.AccessEntry
   114  		actManifest *api.Manifest
   115  		accessKey   []byte
   116  		err         error
   117  		ref         = args[0]
   118  		grantees    = []string{}
   119  		actFilename = ctx.String(SwarmAccessGrantKeysFlag.Name)
   120  		privateKey  = getPrivKey(ctx)
   121  		dryRun      = ctx.Bool(SwarmDryRunFlag.Name)
   122  	)
   123  
   124  	bytes, err := ioutil.ReadFile(actFilename)
   125  	if err != nil {
   126  		utils.Fatalf("had an error reading the grantee public key list")
   127  	}
   128  	grantees = strings.Split(string(bytes), "\n")
   129  	accessKey, ae, actManifest, err = api.DoACTNew(ctx, privateKey, salt, grantees)
   130  	if err != nil {
   131  		utils.Fatalf("error generating ACT manifest: %v", err)
   132  	}
   133  
   134  	if err != nil {
   135  		utils.Fatalf("error getting session key: %v", err)
   136  	}
   137  	m, err := api.GenerateAccessControlManifest(ctx, ref, accessKey, ae)
   138  	if err != nil {
   139  		utils.Fatalf("error generating root access manifest: %v", err)
   140  	}
   141  
   142  	if dryRun {
   143  		err = printManifests(m, actManifest)
   144  		if err != nil {
   145  			utils.Fatalf("had an error printing the manifests: %v", err)
   146  		}
   147  	} else {
   148  		err = uploadManifests(ctx, m, actManifest)
   149  		if err != nil {
   150  			utils.Fatalf("had an error uploading the manifests: %v", err)
   151  		}
   152  	}
   153  }
   154  
   155  func printManifests(rootAccessManifest, actManifest *api.Manifest) error {
   156  	js, err := json.Marshal(rootAccessManifest)
   157  	if err != nil {
   158  		return err
   159  	}
   160  	fmt.Println(string(js))
   161  
   162  	if actManifest != nil {
   163  		js, err := json.Marshal(actManifest)
   164  		if err != nil {
   165  			return err
   166  		}
   167  		fmt.Println(string(js))
   168  	}
   169  	return nil
   170  }
   171  
   172  func uploadManifests(ctx *cli.Context, rootAccessManifest, actManifest *api.Manifest) error {
   173  	bzzapi := strings.TrimRight(ctx.GlobalString(SwarmApiFlag.Name), "/")
   174  	client := client.NewClient(bzzapi)
   175  
   176  	var (
   177  		key string
   178  		err error
   179  	)
   180  	if actManifest != nil {
   181  		key, err = client.UploadManifest(actManifest, false)
   182  		if err != nil {
   183  			return err
   184  		}
   185  
   186  		rootAccessManifest.Entries[0].Access.Act = key
   187  	}
   188  	key, err = client.UploadManifest(rootAccessManifest, false)
   189  	if err != nil {
   190  		return err
   191  	}
   192  	fmt.Println(key)
   193  	return nil
   194  }
   195  
   196  // makePasswordList reads password lines from the file specified by the global --password flag
   197  // and also by the same subcommand --password flag.
   198  // This function ia a fork of utils.MakePasswordList to lookup cli context for subcommand.
   199  // Function ctx.SetGlobal is not setting the global flag value that can be accessed
   200  // by ctx.GlobalString using the current version of cli package.
   201  func makePasswordList(ctx *cli.Context) []string {
   202  	path := ctx.GlobalString(utils.PasswordFileFlag.Name)
   203  	if path == "" {
   204  		path = ctx.String(utils.PasswordFileFlag.Name)
   205  		if path == "" {
   206  			return nil
   207  		}
   208  	}
   209  	text, err := ioutil.ReadFile(path)
   210  	if err != nil {
   211  		utils.Fatalf("Failed to read password file: %v", err)
   212  	}
   213  	lines := strings.Split(string(text), "\n")
   214  	// Sanitise DOS line endings.
   215  	for i := range lines {
   216  		lines[i] = strings.TrimRight(lines[i], "\r")
   217  	}
   218  	return lines
   219  }