示例#1
0
func (s *XLSuite) makeHostAndKeys(c *C, rng *xr.PRNG) (
	n *xn.Node, ckPriv, skPriv *rsa.PrivateKey) {

	// XXX names may not be unique
	name := rng.NextFileName(6)
	for {
		first := string(name[0])
		if !strings.Contains(first, "0123456789") &&
			!strings.Contains(name, "-") {
			break
		}
		name = rng.NextFileName(6)
	}
	id := s.makeANodeID(c, rng)
	lfs := "tmp/" + hex.EncodeToString(id.Value())
	ckPriv = s.makeAnRSAKey(c)
	skPriv = s.makeAnRSAKey(c)

	n, err2 := xn.New(name, id, lfs, ckPriv, skPriv, nil, nil, nil)

	c.Assert(err2, IsNil)
	c.Assert(n, Not(IsNil))
	c.Assert(name, Equals, n.GetName())
	actualID := n.GetNodeID()
	c.Assert(true, Equals, id.Equal(actualID))
	// s.doKeyTests(c, n, rng)
	c.Assert(0, Equals, (*n).SizePeers())
	c.Assert(0, Equals, (*n).SizeOverlays())
	c.Assert(0, Equals, n.SizeConnections())
	c.Assert(lfs, Equals, n.GetLFS())
	return n, ckPriv, skPriv
}
示例#2
0
func NewUserMember(
	name, lfs string, ckPriv, skPriv *rsa.PrivateKey,
	serverName string, serverID *xi.NodeID, serverEnd xt.EndPointI,
	serverCK, serverSK *rsa.PublicKey,
	clusterName string, clusterAttrs uint64, clusterID *xi.NodeID,
	size, epCount uint32, e []xt.EndPointI) (ac *UserMember, err error) {

	var attrs uint64

	nodeID, err := xi.New(nil)
	if err == nil {
		if lfs == "" {
			attrs |= xcl.ATTR_EPHEMERAL
		}
		node, err := xn.New(name, nodeID, lfs, ckPriv, skPriv, nil, nil, nil)
		if err == nil {
			mn, err := NewMemberMaker(node,
				attrs,
				serverName, serverID, serverEnd,
				serverCK, serverSK, //  *rsa.PublicKey,
				clusterName, clusterAttrs, clusterID, size,
				epCount, e)

			if err == nil {
				// Start() fills in clusterID
				ac = &UserMember{
					MemberMaker: *mn,
				}
			}
		}
	}
	return

}
示例#3
0
func NewMockUpaxClient(name, lfs string, members []*xcl.MemberInfo,
	primary uint) (mc *MockUpaxClient, err error) {
	var (
		ckPriv, skPriv *rsa.PrivateKey
		ep             []xt.EndPointI
		node           *xn.Node
		uc             *UpaxClient
	)

	// lfs should be a well-formed POSIX path; if the directory does
	// not exist we should create it.
	err = xf.CheckLFS(lfs, 0750)

	// The ckPriv is an RSA key used to encrypt short messages.
	if err == nil {
		if ckPriv == nil {
			ckPriv, err = rsa.GenerateKey(rand.Reader, 2048)
		}
		if err == nil {
			// The skPriv is an RSA key used to create digital signatures.
			if skPriv == nil {
				skPriv, err = rsa.GenerateKey(rand.Reader, 2048)
			}
		}
	}
	// The mock client uses a system-assigned endpoint
	if err == nil {
		var endPoint *xt.TcpEndPoint
		endPoint, err = xt.NewTcpEndPoint("127.0.0.1:0")
		if err == nil {
			ep = []xt.EndPointI{endPoint}
		}
	}
	// spin up an XLattice node
	if err == nil {
		node, err = xn.New(name, nil, // get a default NodeID
			lfs, ckPriv, skPriv, nil, ep, nil) // nil overlays, peers
	}
	if err == nil {
		uc, err = NewUpaxClient(ckPriv, skPriv, node, members, primary)
		if err == nil {
			mc = &MockUpaxClient{
				UpaxClient: *uc,
			}
		}
	}
	return
}
示例#4
0
func New(name string, id *xi.NodeID, lfs string,
	commsKey, sigKey *rsa.PrivateKey,
	o []xo.OverlayI, e []xt.EndPointI, p []*xn.Peer) (
	uNode *UpaxNode, err error) {

	n, err := xn.New(name, id, lfs, commsKey, sigKey, o, e, p)

	if err == nil {
		uNode = &UpaxNode{
			ckPriv: commsKey,
			skPriv: sigKey,
			Node:   *n,
		}
	}
	return
}
示例#5
0
func (s *XLSuite) TestCrytpo(c *C) {
	if VERBOSITY > 0 {
		fmt.Println("TEST_CRYPTO")
	}
	rng := xr.MakeSimpleRNG()
	nodeID := s.makeANodeID(c, rng)

	ckPriv := s.makeAnRSAKey(c)
	skPriv := s.makeAnRSAKey(c)

	node, err := xn.New("foo", nodeID, "", ckPriv, skPriv, nil, nil, nil)
	c.Assert(err, IsNil)
	c.Assert(node, Not(IsNil))

	ck := node.GetCommsPublicKey()

	// XXX ADDING 4 BYTE VERSION NUMBER

	// Generate 16-byte AES IV, 32-byte AES key, and 8-byte salt
	// and 4-byte version number for the Hello and another 20 bytes as salt
	// for the OAEP encrypt. For testing purposes these need not be crypto
	// grade.

	salty := make([]byte, 3*aes.BlockSize+8+4+xu.SHA1_BIN_LEN)
	rng.NextBytes(salty)

	iv1 := salty[:aes.BlockSize]
	key1 := salty[aes.BlockSize : 3*aes.BlockSize]
	salt1 := salty[3*aes.BlockSize : 3*aes.BlockSize+8]
	vBytes := salty[3*aes.BlockSize+8 : 3*aes.BlockSize+12]
	version1 := uint32(
		(0xff & vBytes[3] << 24) | (0xff & vBytes[2] << 16) |
			(0xff & vBytes[1] << 8) | (0xff & vBytes[0]))
	_ = version1 // DEBUG
	oaep1 := salty[3*aes.BlockSize+12:]

	oaepSalt := bytes.NewBuffer(oaep1)

	// == HELLO =====================================================
	// On the client side:

	// Create and marshal a hello containing AES iv1, key1, salt1, version1.
	//
	// There is no reason at all to use protobufs for this purpose.
	// Just encrypt iv1 + key1 + salt1 + version1
	sha := sha1.New()
	data := salty[:3*aes.BlockSize+8+4] // contains iv1,key1,salt1,version1
	c.Assert(len(data), Equals, 60)

	ciphertext, err := rsa.EncryptOAEP(sha, oaepSalt, ck, data, nil)
	c.Assert(err, IsNil)
	c.Assert(ciphertext, Not(IsNil))

	// On the server side: ------------------------------------------
	// decrypt the hello using the node's private comms key
	plaintext, err := rsa.DecryptOAEP(sha, nil, ckPriv, ciphertext, nil)
	c.Assert(err, IsNil)
	c.Assert(plaintext, Not(IsNil))

	// verify that iv1, key1, salt1, version1 are the same
	c.Assert(data, DeepEquals, plaintext)

	// == HELLO REPLY ===============================================
	// On the server side:
	//
	// Create, marshal a reply containing iv2, key2, salt2, salt1, version2
	// This could be done as a Protobuf message, but is handled as a simple
	// byte slice instead.

	// create the session iv + key plus salt2
	reply := make([]byte, 3*aes.BlockSize+8)
	rng.NextBytes(reply)

	iv2 := reply[:aes.BlockSize]
	key2 := reply[aes.BlockSize : 3*aes.BlockSize]
	salt2 := reply[3*aes.BlockSize]

	reply = append(reply, salt1...)
	reply = append(reply, vBytes...)

	// We need padding because the message is not or may not be an
	// integer multiple of the block size.

	paddedReply, err := xc.AddPKCS7Padding(reply, aes.BlockSize)
	c.Assert(err, IsNil)
	c.Assert(paddedReply, Not(IsNil))

	// encrypt the reply using engine1a = iv1, key1
	engine1a, err := aes.NewCipher(key1) // on server
	c.Assert(err, IsNil)
	c.Assert(engine1a, Not(IsNil))

	aesEncrypter1a := cipher.NewCBCEncrypter(engine1a, iv1)
	c.Assert(err, IsNil)
	c.Assert(aesEncrypter1a, Not(IsNil))

	// we require that the message size be a multiple of the block size
	c.Assert(aesEncrypter1a.BlockSize(), Equals, aes.BlockSize)
	msgLen := len(paddedReply)
	nBlocks := (msgLen + aes.BlockSize - 1) / aes.BlockSize
	c.Assert(msgLen, Equals, nBlocks*aes.BlockSize)

	ciphertext = make([]byte, nBlocks*aes.BlockSize)
	aesEncrypter1a.CryptBlocks(ciphertext, paddedReply) // dest <- src

	// On the client side: ------------------------------------------
	//     decrypt the reply using engine1b = iv1, key1

	engine1b, err := aes.NewCipher(key1) // on client
	c.Assert(err, IsNil)
	c.Assert(engine1b, Not(IsNil))

	aesDecrypter1b := cipher.NewCBCDecrypter(engine1b, iv1)
	c.Assert(err, IsNil)
	c.Assert(aesDecrypter1b, Not(IsNil))

	plaintext = make([]byte, nBlocks*aes.BlockSize)
	aesDecrypter1b.CryptBlocks(plaintext, ciphertext) // dest <- src

	c.Assert(plaintext, DeepEquals, paddedReply)
	unpaddedReply, err := xc.StripPKCS7Padding(paddedReply, aes.BlockSize)
	c.Assert(err, IsNil)
	c.Assert(unpaddedReply, DeepEquals, reply)

	_ = salt2 // WE DON'T USE THIS YET

	// AES HANDLING FOR ALL FURTHER MESSAGES ========================

	// -- CLIENT-SIDE AES SETUP -----------------
	// encrypt the client msg using engineC = iv2, key2

	engineC, err := aes.NewCipher(key2)
	c.Assert(err, IsNil)
	c.Assert(engineC, Not(IsNil))

	encrypterC := cipher.NewCBCEncrypter(engineC, iv2)
	c.Assert(err, IsNil)
	c.Assert(encrypterC, Not(IsNil))

	decrypterC := cipher.NewCBCDecrypter(engineC, iv2)
	c.Assert(err, IsNil)
	c.Assert(decrypterC, Not(IsNil))

	// we require that the message size be a multiple of the block size
	c.Assert(encrypterC.BlockSize(), Equals, aes.BlockSize)
	c.Assert(decrypterC.BlockSize(), Equals, aes.BlockSize)

	// -- SERVER-SIDE AES SETUP -----------------
	engineS, err := aes.NewCipher(key2)
	c.Assert(err, IsNil)
	c.Assert(engineS, Not(IsNil))

	encrypterS := cipher.NewCBCEncrypter(engineS, iv2)
	c.Assert(err, IsNil)
	c.Assert(encrypterS, Not(IsNil))

	decrypterS := cipher.NewCBCDecrypter(engineS, iv2)
	c.Assert(err, IsNil)
	c.Assert(decrypterS, Not(IsNil))

	// we require that the message size be a multiple of the block size
	c.Assert(encrypterS.BlockSize(), Equals, aes.BlockSize)
	c.Assert(decrypterS.BlockSize(), Equals, aes.BlockSize)

	//// == CLIENT MSG ================================================
	//// On the client side:

	//// create and marshal client name, specs, salt2, digsig over that
	//clientName := rng.NextFileName(8)

	//// create and marshal a token containing attrs, id, ck, sk, myEnd*
	//attrs := uint64(947)
	//ckBytes, err := xc.RSAPrivateKeyToWire(ckPriv)
	//c.Assert(err, IsNil)
	//skBytes, err := xc.RSAPrivateKeyToWire(skPriv)
	//c.Assert(err, IsNil)

	//myEnd := []string{"127.0.0.1:4321"}
	//token := &XLRegMsg_Token{
	//	Attrs:    &attrs,
	//	ID:       nodeID.Value(),
	//	CommsKey: ckBytes,
	//	SigKey:   skBytes,
	//	MyEnd:    myEnd,
	//}

	//op := XLRegMsg_Client
	//clientMsg := XLRegMsg{
	//	Op:          &op,
	//	ClientName:  &clientName,
	//	ClientSpecs: token,
	//}

	//ciphertext, err = EncodePadEncrypt(&clientMsg, encrypterC)
	//c.Assert(err, IsNil)

	//// On the server side: ------------------------------------------
	//clientMsg2, err := DecryptUnpadDecode(ciphertext, decrypterS)
	//c.Assert(err, IsNil)

	//c.Assert(clientMsg2.GetOp(), Equals, XLRegMsg_Client)

	//// verify that id, ck, sk, myEnd* survive the trip unchanged

	//name2 := clientMsg2.GetClientName()
	//c.Assert(name2, Equals, clientName)

	//clientSpecs2 := clientMsg2.GetClientSpecs()
	//c.Assert(clientSpecs2, Not(IsNil))

	//attrs2 := clientSpecs2.GetAttrs()
	//id2 := clientSpecs2.GetID()
	//ckBytes2 := clientSpecs2.GetCommsKey()
	//skBytes2 := clientSpecs2.GetSigKey()
	//myEnd2 := clientSpecs2.GetMyEnd() // a string array

	//c.Assert(attrs2, Equals, attrs)
	//c.Assert(id2, DeepEquals, nodeID.Value())
	//c.Assert(ckBytes2, DeepEquals, ckBytes)
	//c.Assert(skBytes2, DeepEquals, skBytes)
	//c.Assert(myEnd2, DeepEquals, myEnd)

	//// == CLIENT OK =================================================
	//// on the server side:

	//clientID := s.makeAnID(c, rng)
	//attrsBack := uint64(479)

	//op = XLRegMsg_ClientOK
	//clientOKMsg := XLRegMsg{
	//	Op:       &op,
	//	ClientID: clientID,
	//	Attrs:    &attrsBack,
	//}
	//ciphertext, err = EncodePadEncrypt(&clientOKMsg, encrypterS)
	//c.Assert(err, IsNil)

	//// on the client side -------------------------------------------
	//clientOK2, err := DecryptUnpadDecode(ciphertext, decrypterC)
	//c.Assert(err, IsNil)

	//c.Assert(clientOK2.GetOp(), Equals, XLRegMsg_ClientOK)
	//clientID2 := clientOK2.GetClientID()
	//c.Assert(clientID2, DeepEquals, clientID)
	//attrsBack2 := clientOK2.GetAttrs()
	//c.Assert(attrsBack2, Equals, attrsBack)

	//// == CREATE ====================================================
	//// on the client side:
	//clusterName := rng.NextFileName(8)
	//clusterSize := uint32(2 + rng.Intn(60))

	//op = XLRegMsg_Create
	//createMsg := XLRegMsg{
	//	Op:          &op,
	//	ClusterName: &clusterName,
	//	ClusterSize: &clusterSize,
	//}
	//ciphertext, err = EncodePadEncrypt(&createMsg, encrypterC)
	//c.Assert(err, IsNil)

	//// on the server side -------------------------------------------
	//createMsg2, err := DecryptUnpadDecode(ciphertext, decrypterS)
	//c.Assert(err, IsNil)

	//c.Assert(createMsg2.GetOp(), Equals, XLRegMsg_Create)
	//clusterName2 := createMsg2.GetClusterName()
	//c.Assert(clusterName2, Equals, clusterName)
	//clusterSize2 := createMsg2.GetClusterSize()
	//c.Assert(clusterSize2, Equals, clusterSize)

	//// == CREATE REPLY ==============================================
	//// on the server side:
	//clusterID := s.makeAnID(c, rng)
	//sizeBack := uint32(2 + rng.Intn(60))

	//op = XLRegMsg_CreateReply
	//createReplyMsg := XLRegMsg{
	//	Op:          &op,
	//	ClusterID:   clusterID,
	//	ClusterSize: &sizeBack,
	//}
	//ciphertext, err = EncodePadEncrypt(&createReplyMsg, encrypterS)
	//c.Assert(err, IsNil)

	//// on the client side -------------------------------------------
	//createReply2, err := DecryptUnpadDecode(ciphertext, decrypterC)
	//c.Assert(err, IsNil)

	//c.Assert(createReply2.GetOp(), Equals, XLRegMsg_CreateReply)
	//clusterID2 := createReply2.GetClusterID()
	//c.Assert(clusterID2, DeepEquals, clusterID)
	//sizeBack2 := createReply2.GetClusterSize()
	//c.Assert(sizeBack2, Equals, sizeBack)

	//// == JOIN ======================================================
	//// On the client side:
	//op = XLRegMsg_Join
	//joinMsg := XLRegMsg{
	//	Op:        &op,
	//	ClusterID: clusterID,
	//}
	//ciphertext, err = EncodePadEncrypt(&joinMsg, encrypterC)
	//c.Assert(err, IsNil)

	//// on the server side -------------------------------------------
	//join2, err := DecryptUnpadDecode(ciphertext, decrypterS)
	//c.Assert(err, IsNil)

	//c.Assert(join2.GetOp(), Equals, XLRegMsg_Join)
	//clusterID2 = join2.GetClusterID()
	//c.Assert(clusterID2, DeepEquals, clusterID) // GEEP

	//// == JOIN REPLY ================================================
	//// on the server side:
	//op = XLRegMsg_JoinReply
	//joinReplyMsg := XLRegMsg{
	//	Op:          &op,
	//	ClusterID:   clusterID,
	//	ClusterSize: &clusterSize,
	//}
	//ciphertext, err = EncodePadEncrypt(&joinReplyMsg, encrypterS)
	//c.Assert(err, IsNil)

	//// on the client side -------------------------------------------
	//joinReply2, err := DecryptUnpadDecode(ciphertext, decrypterC)
	//c.Assert(err, IsNil)

	//c.Assert(joinReply2.GetOp(), Equals, XLRegMsg_JoinReply)
	//clusterID2 = joinReply2.GetClusterID()
	//c.Assert(clusterID2, DeepEquals, clusterID)
	//sizeBack = joinReply2.GetClusterSize()
	//c.Assert(sizeBack, Equals, clusterSize)

	//// == GET =======================================================
	//// On the client side:

	//// on the server side -------------------------------------------

	//// == MEMBERS ===================================================
	//// On the server side:

	//// on the client side -------------------------------------------

	//// create and marshal a set of 3=5 tokens each containing attrs,
	//// nodeID, clusterID
	//// XXX STUB XXX

	//// encrypt the msg using engineC = iv2, key2
	//// XXX STUB XXX

	//// decrypt the msg using engineS = iv2, key2
	//// XXX STUB XXX

	//// verify that the various tokens (id, ck, sk, myEnd*) survive the
	//// trip unchanged
	//// XXX STUB XXX

	//// == BYE =======================================================
	//// On the client side:
	//op = XLRegMsg_Bye
	//byeMsg := XLRegMsg{
	//	Op: &op,
	//}
	//ciphertext, err = EncodePadEncrypt(&byeMsg, encrypterC)
	//c.Assert(err, IsNil)

	//// on the server side -------------------------------------------
	//bye2, err := DecryptUnpadDecode(ciphertext, decrypterS)
	//c.Assert(err, IsNil)
	//c.Assert(bye2.GetOp(), Equals, XLRegMsg_Bye)

	//// == ACK =======================================================
	//// on the server side:
	//op = XLRegMsg_Ack
	//ackMsg := XLRegMsg{
	//	Op: &op,
	//}
	//ciphertext, err = EncodePadEncrypt(&ackMsg, encrypterS)
	//c.Assert(err, IsNil)

	//// on the client side -------------------------------------------
	//ack2, err := DecryptUnpadDecode(ciphertext, decrypterC)
	//c.Assert(err, IsNil)
	//c.Assert(ack2.GetOp(), Equals, XLRegMsg_Ack)
}
示例#6
-1
func NewEphServer() (ms *EphServer, err error) {

	// Create an XLattice node with quasi-random parameters including
	// low-quality keys and an endPoint in 127.0.0.1, localhost.
	var (
		ckPriv, skPriv *rsa.PrivateKey
		rn             *RegNode
		ep             *xt.TcpEndPoint
		node           *xn.Node
		reg            *Registry
		server         *RegServer
	)

	rng := xr.MakeSimpleRNG()
	name := rng.NextFileName(16)
	idBuf := make([]byte, xu.SHA1_BIN_LEN)
	rng.NextBytes(idBuf)
	lfs := "tmp/" + hex.EncodeToString(idBuf)
	id, err := xi.New(nil)
	if err == nil {
		// XXX cheap keys, too weak for any serious use
		ckPriv, err = rsa.GenerateKey(rand.Reader, 1024)
		if err == nil {
			skPriv, err = rsa.GenerateKey(rand.Reader, 1024)
		}
	}
	if err == nil {
		ep, err = xt.NewTcpEndPoint("127.0.0.1:0")
		eps := []xt.EndPointI{ep}
		if err == nil {
			node, err = xn.New(name, id, lfs, ckPriv, skPriv, nil, eps, nil)
			if err == nil {
				err = node.OpenAcc() // so acceptors are now live
				if err == nil {
					rn, err = NewRegNode(node, ckPriv, skPriv)
					if err == nil {
						// DEBUG
						if rn == nil {
							fmt.Println("regNode is NIL!\n")
						} else {
							fmt.Printf("eph server listening on %s\n",
								rn.GetAcceptor(0).String())
						}
						// END
						// a registry with no clusters and no logger
						opt := &RegOptions{
							EndPoint:       ep, // not used
							Ephemeral:      true,
							GlobalEndPoint: node.GetEndPoint(0),
							Lfs:            lfs, // redundant (is in node's BaseNode)
							Logger:         nil,
							K:              DEFAULT_K,
							M:              DEFAULT_M,
						}
						reg, err = NewRegistry(nil, rn, opt)
						if err == nil {
							server, err = NewRegServer(reg, true, 1)
							if err == nil {
								ms = &EphServer{
									acc:    rn.GetAcceptor(0),
									Server: server,
								}
							}
						}
					}
				}
			}
		}
	}
	return
}
示例#7
-1
文件: xlReg.go 项目: jddixon/xlReg_go
func setup(opt *reg.RegOptions) (rs *reg.RegServer, err error) {
	// If LFS/.xlattice/reg.config exists, we load that.  Otherwise we
	// create a node.  In either case we force the node to listen on
	// the designated port

	var (
		e                []xt.EndPointI
		node             *xn.Node
		pathToConfigFile string
		rn               *reg.RegNode
		ckPriv, skPriv   *rsa.PrivateKey
	)
	logger := opt.Logger
	verbose := opt.Verbose

	greetings := fmt.Sprintf("xlReg v%s %s start run\n",
		reg.VERSION, reg.VERSION_DATE)
	if verbose {
		fmt.Print(greetings)
	}
	logger.Print(greetings)

	pathToConfigFile = path.Join(path.Join(opt.Lfs, ".xlattice"), "reg.config")
	found, err := xf.PathExists(pathToConfigFile)
	if err == nil {
		if found {
			logger.Printf("Loading existing reg config from %s\n",
				pathToConfigFile)
			// The registry node already exists.  Parse it and we are done.
			var data []byte
			data, err = ioutil.ReadFile(pathToConfigFile)
			if err == nil {
				rn, _, err = reg.ParseRegNode(string(data))
			}
		} else {
			logger.Println("No config file found, creating new registry.")
			// We need to create a registry node from scratch.
			nodeID, _ := xi.New(nil)
			ep, err := xt.NewTcpEndPoint(opt.Address + ":" + opt.Port)
			if err == nil {
				e = []xt.EndPointI{ep}
				ckPriv, err = rsa.GenerateKey(rand.Reader, 2048)
				if err == nil {
					skPriv, err = rsa.GenerateKey(rand.Reader, 2048)
				}
				if err == nil {
					node, err = xn.New("xlReg", nodeID, opt.Lfs, ckPriv, skPriv,
						nil, e, nil)
					if err == nil {
						node.OpenAcc() // XXX needs a complementary close
						if err == nil {
							// DEBUG
							fmt.Printf("XLattice node successfully created\n")
							fmt.Printf("  listening on %s\n", ep.String())
							// END
							rn, err = reg.NewRegNode(node, ckPriv, skPriv)
							if err == nil {
								// DEBUG
								fmt.Printf("regNode successfully created\n")
								// END
								err = xf.MkdirsToFile(pathToConfigFile, 0700)
								if err == nil {
									err = ioutil.WriteFile(pathToConfigFile,
										[]byte(rn.String()), 0400)
									// DEBUG
								} else {
									fmt.Printf("error writing config file: %v\n",
										err.Error())
								}
								// END --------------

								// DEBUG
							} else {
								fmt.Printf("error creating regNode: %v\n",
									err.Error())
								// END
							}
						}
					}
				}
			}
		}
	}
	if err == nil {
		var r *reg.Registry
		r, err = reg.NewRegistry(nil, // nil = clusters so far
			rn, opt) // regNode, options
		if err == nil {
			logger.Printf("Registry name: %s\n", rn.GetName())
			logger.Printf("         ID:   %s\n", rn.GetNodeID().String())
		}
		if err == nil {
			var verbosity int
			if opt.Verbose {
				verbosity++
			}
			rs, err = reg.NewRegServer(r, opt.Testing, verbosity)
		}
	}
	if err != nil {
		logger.Printf("ERROR: %s\n", err.Error())
	}
	return
}