@cryptotaxi247 / kubo / commits / 235a76749

implement namesys resolvers (thanks to bren2010 for dns and proquint)

Jeromy committed Sep 10, 2014 at 16:55 UTC 235a7674929ec787c141abec96b11534023a159c
9 files changed +257 -1
cmd/ipfs/pin.go new
+44
@@ -0,0 +1,44 @@
1 +package main
2 +
3 +import (
4 + "os"
5 +
6 + "github.com/gonuts/flag"
7 + "github.com/jbenet/commander"
8 + "github.com/jbenet/go-ipfs/daemon"
9 + u "github.com/jbenet/go-ipfs/util"
10 +)
11 +
12 +var cmdIpfsPin = &commander.Command{
13 + UsageLine: "pin",
14 + Short: "pin an ipfs object to local storage.",
15 + Long: `ipfs pin <ipfs-path> - pin ipfs object to local storage.
16 +
17 + Retrieves the object named by <ipfs-path> and stores it locally
18 + on disk.
19 +`,
20 + Run: pinCmd,
21 + Flag: *flag.NewFlagSet("ipfs-pin", flag.ExitOnError),
22 +}
23 +
24 +func pinCmd(c *commander.Command, inp []string) error {
25 + if len(inp) < 1 {
26 + u.POut(c.Long)
27 + return nil
28 + }
29 +
30 + com := daemon.NewCommand()
31 + com.Command = "pin"
32 + com.Args = inp
33 +
34 + err := daemon.SendCommand(com, "localhost:12345")
35 + if err != nil {
36 + n, err := localNode(false)
37 + if err != nil {
38 + return err
39 + }
40 +
41 + daemon.ExecuteCommand(com, n, os.Stdout)
42 + }
43 + return nil
44 +}
core/core.go
+1 -1
@@ -60,7 +60,7 @@ type IpfsNode struct {
60 Resolver *path.Resolver
61
62 // the name system, resolves paths to hashes
63 - // Namesys *namesys.Namesys
63 + Namesys namesys.NSResolver
64 }
65
66 // NewIpfsNode constructs a new IpfsNode based on the given config.
namesys/dns.go new
+33
@@ -0,0 +1,33 @@
1 +package namesys
2 +
3 +import (
4 + "net"
5 + "strings"
6 +
7 + u "github.com/jbenet/go-ipfs/util"
8 +)
9 +
10 +type DNSResolver struct {
11 + // TODO: maybe some sort of caching?
12 + // cache would need a timeout
13 +}
14 +
15 +func (r *DNSResolver) Resolve(name string) (string, error) {
16 + txt, err := net.LookupTXT(name)
17 + if err != nil {
18 + return "", err
19 + }
20 +
21 + for _, t := range txt {
22 + pair := strings.Split(t, "=")
23 + if len(pair) < 2 {
24 + // Log error?
25 + u.DErr("Incorrectly formatted text record.")
26 + continue
27 + }
28 + if pair[0] == name {
29 + return pair[1], nil
30 + }
31 + }
32 + return "", u.ErrNotFound
33 +}
namesys/entry.pb.go new
+48
@@ -0,0 +1,48 @@
1 +// Code generated by protoc-gen-go.
2 +// source: entry.proto
3 +// DO NOT EDIT!
4 +
5 +/*
6 +Package namesys is a generated protocol buffer package.
7 +
8 +It is generated from these files:
9 + entry.proto
10 +
11 +It has these top-level messages:
12 + InpsEntry
13 +*/
14 +package namesys
15 +
16 +import proto "code.google.com/p/goprotobuf/proto"
17 +import math "math"
18 +
19 +// Reference imports to suppress errors if they are not otherwise used.
20 +var _ = proto.Marshal
21 +var _ = math.Inf
22 +
23 +type InpsEntry struct {
24 + Value []byte `protobuf:"bytes,1,req,name=value" json:"value,omitempty"`
25 + Signature []byte `protobuf:"bytes,2,req,name=signature" json:"signature,omitempty"`
26 + XXX_unrecognized []byte `json:"-"`
27 +}
28 +
29 +func (m *InpsEntry) Reset() { *m = InpsEntry{} }
30 +func (m *InpsEntry) String() string { return proto.CompactTextString(m) }
31 +func (*InpsEntry) ProtoMessage() {}
32 +
33 +func (m *InpsEntry) GetValue() []byte {
34 + if m != nil {
35 + return m.Value
36 + }
37 + return nil
38 +}
39 +
40 +func (m *InpsEntry) GetSignature() []byte {
41 + if m != nil {
42 + return m.Signature
43 + }
44 + return nil
45 +}
46 +
47 +func init() {
48 +}
namesys/entry.proto new
+6
@@ -0,0 +1,6 @@
1 +package namesys;
2 +
3 +message InpsEntry {
4 + required bytes value = 1;
5 + required bytes signature = 2;
6 +}
namesys/nsresolver.go new
+5
@@ -0,0 +1,5 @@
1 +package namesys
2 +
3 +type NSResolver interface {
4 + Resolve(string) (string, error)
5 +}
namesys/proquint.go new
+22
@@ -0,0 +1,22 @@
1 +package namesys
2 +
3 +import (
4 + "errors"
5 +
6 + proquint "github.com/bren2010/proquint"
7 +)
8 +
9 +var _ = proquint.Encode
10 +
11 +type ProquintResolver struct{}
12 +
13 +func (r *ProquintResolver) Resolve(name string) (string, error) {
14 + ok, err := proquint.IsProquint(name)
15 + if err != nil {
16 + return "", err
17 + }
18 + if !ok {
19 + return "", errors.New("not a valid proquint string")
20 + }
21 + return string(proquint.Decode(name)), nil
22 +}
namesys/resolver.go new
+21
@@ -0,0 +1,21 @@
1 +package namesys
2 +
3 +import "strings"
4 +
5 +type MasterResolver struct {
6 + dns *DNSResolver
7 + routing *RoutingResolver
8 + pro *ProquintResolver
9 +}
10 +
11 +func (mr *MasterResolver) Resolve(name string) (string, error) {
12 + if strings.Contains(name, ".") {
13 + return mr.dns.Resolve(name)
14 + }
15 +
16 + if strings.Contains(name, "-") {
17 + return mr.pro.Resolve(name)
18 + }
19 +
20 + return mr.routing.Resolve(name)
21 +}
namesys/routing.go new
+77
@@ -0,0 +1,77 @@
1 +package namesys
2 +
3 +import (
4 + "fmt"
5 + "time"
6 +
7 + "code.google.com/p/goprotobuf/proto"
8 +
9 + ci "github.com/jbenet/go-ipfs/crypto"
10 + mdag "github.com/jbenet/go-ipfs/merkledag"
11 + "github.com/jbenet/go-ipfs/routing"
12 + u "github.com/jbenet/go-ipfs/util"
13 + mh "github.com/jbenet/go-multihash"
14 +)
15 +
16 +// RoutingName is the de-serialized name structure that is stored (serialized)
17 +// in the routing system. Basically, a hash + a digital signature. (serialization can be
18 +// protobuf, or a simple binary format)
19 +type RoutingName struct {
20 + Hash u.Key
21 + Signature []byte
22 +}
23 +
24 +// RoutingResolver implements NSResolver for the main IPFS SFS-like naming
25 +type RoutingResolver struct {
26 + routing routing.IpfsRouting
27 + dag mdag.DAGService
28 +}
29 +
30 +func (r *RoutingResolver) Resolve(name string) (string, error) {
31 + hash, err := mh.FromB58String(name)
32 + if err != nil {
33 + return "", err
34 + }
35 + // name should be a multihash. if it isn't, error out here.
36 +
37 + // use the routing system to get the name.
38 + // /ipns/<name>
39 + h, err := u.Hash([]byte("ipns:" + name))
40 + if err != nil {
41 + return "", err
42 + }
43 +
44 + inpsKey := u.Key(h)
45 + val, err := r.routing.GetValue(inpsKey, time.Second*10)
46 + if err != nil {
47 + return "", err
48 + }
49 +
50 + entry := new(InpsEntry)
51 + err = proto.Unmarshal(val, entry)
52 + if err != nil {
53 + return "", err
54 + }
55 +
56 + // name should be a public key retrievable from ipfs
57 + // /ipfs/<name>
58 + key := u.Key(hash)
59 + node, err := r.dag.Get(key)
60 + if err != nil {
61 + return "", err
62 + }
63 +
64 + // get PublicKey from node.Data
65 + pk, err := ci.UnmarshalPublicKey(node.Data)
66 + if err != nil {
67 + return "", err
68 + }
69 +
70 + // check sig with pk
71 + if ok, err := pk.Verify(entry.GetValue(), entry.GetSignature()); err != nil && ok {
72 + return "", fmt.Errorf("Invalid value. Not signed by PrivateKey corresponding to %v", pk)
73 + }
74 +
75 + // ok sig checks out. this is a valid name.
76 + return string(entry.GetValue()), nil
77 +}