func NewMemberInfoFromToken(token *XLRegMsg_Token) ( m *xcl.MemberInfo, err error) { var ( ck, sk *rsa.PublicKey ctor xt.ConnectorI ctors []xt.ConnectorI farEnd xt.EndPointI nodeID *xi.NodeID peer *xn.Peer ) if token == nil { err = NilToken } else { nodeID, err = xi.New(token.GetID()) if err == nil { ck, err = xc.RSAPubKeyFromWire(token.GetCommsKey()) if err == nil { sk, err = xc.RSAPubKeyFromWire(token.GetSigKey()) if err == nil { attrs := token.GetAttrs() myEnds := token.GetMyEnds() for i := 0; i < len(myEnds); i++ { myEnd := myEnds[i] farEnd, err = xt.NewTcpEndPoint(myEnd) if err != nil { break } ctor, err = xt.NewTcpConnector(farEnd) if err != nil { break } ctors = append(ctors, ctor) } if err == nil { peer, err = xn.NewPeer(token.GetName(), nodeID, ck, sk, nil, ctors) if err == nil { m = &xcl.MemberInfo{ Attrs: attrs, Peer: peer, } } } } //if err == nil { // m, err = NewMemberInfo(token.GetName(), nodeID, // ck, sk, token.GetAttrs(), token.GetMyEnds()) //} } } } return }
func NewClientInfoFromToken(token *XLRegMsg_Token) ( m *ClientInfo, err error) { var nodeID *xi.NodeID if token == nil { err = NilToken } else { nodeID, err = xi.New(token.GetID()) if err == nil { ck, err := xc.RSAPubKeyFromWire(token.GetCommsKey()) if err == nil { sk, err := xc.RSAPubKeyFromWire(token.GetSigKey()) if err == nil { m, err = NewClientInfo(token.GetName(), nodeID, ck, sk, token.GetAttrs(), token.GetMyEnds()) } } } } return }
func doClientMsg(h *InHandler) { var err error defer func() { h.errOut = err }() // DEBUG regName := h.reg.GetName() h.reg.Logger.Printf("doClientMsg: regName is %s\n", regName) // END // Examine incoming message ------------------------------------- var ( name string attrs uint64 nodeID *xi.NodeID ck, sk *rsa.PublicKey myEnds []string hash []byte cm *ClientInfo ) // XXX We should accept EITHER clientName + token OR clientID // This implementation only accepts a token. clientMsg := h.msgIn clientSpecs := clientMsg.GetMemberSpecs() name = clientSpecs.GetName() attrs = clientSpecs.GetAttrs() ckBytes := clientSpecs.GetCommsKey() skBytes := clientSpecs.GetSigKey() digSig := clientSpecs.GetDigSig() ck, err = xc.RSAPubKeyFromWire(ckBytes) if err == nil { sk, err = xc.RSAPubKeyFromWire(skBytes) if err == nil { myEnds = clientSpecs.GetMyEnds() // a string array } } if err == nil { // calculate hash over fields in canonical order XXX EXCLUDING ID aBytes := make([]byte, 8) binary.LittleEndian.PutUint64(aBytes, attrs) d := sha1.New() d.Write([]byte(name)) d.Write(aBytes) d.Write(ckBytes) d.Write(skBytes) for i := 0; i < len(myEnds); i++ { d.Write([]byte(myEnds[i])) } hash = d.Sum(nil) // verify the digital signature err = rsa.VerifyPKCS1v15(sk, crypto.SHA1, hash, digSig) } if err == nil { id := clientSpecs.GetID() // DEBUG if id == nil { h.reg.Logger.Println(" doClientMsg: id from Specs is NIL") } else { h.reg.Logger.Printf(" doClientMsg: id from Specs is %x\n", id) } // END if id == nil { nodeID, err = h.reg.InsertUniqueNodeID() // DEBUG h.reg.Logger.Printf(" doClientMsg: inserting %x returned %v\n", id, err) // END if err == nil { id := nodeID.Value() // this is echoed to the console h.reg.Logger.Printf("doClientMsg: assigning new MemberID %xi, user %s", id, name) } } else { // must be known to the registry nodeID, err = xi.New(id) if err == nil { var found bool found, err = h.reg.ContainsID(nodeID) if err == nil && !found { err = h.reg.InsertID(nodeID) } } } } // Take appropriate action -------------------------------------- if err == nil || err == IDAlreadyInUse { // The appropriate action is to hang a token for this client off // the InHandler. cm, err = NewClientInfo(name, nodeID, ck, sk, attrs, myEnds) if err == nil { h.thisClient = cm } } if err == nil { // Prepare reply to client -------------------------------------- // In this implementation We simply accept the client's proposed // attrs and ID. op := XLRegMsg_MemberOK h.msgOut = &XLRegMsg{ Op: &op, MemberID: nodeID.Value(), MemberAttrs: &attrs, // in production, review and limit } // Set exit state ----------------------------------------------- h.exitState = CLIENT_DETAILS_RCVD } }