func (d *Director) createIdentity(name string) (*security.Identity, error) { i := security.NewIdentity(name) log.WithFields(log.Fields{ "name": name, }).Info("Creating new identity") i.NewKey() i.NewRequest() return i, nil }
// LoadIdentity loads the identity with the id specified func (s *State) LoadIdentity(id string) (*security.Identity, error) { var ( pemBytes []byte err error ) i := security.NewIdentity(id) pemBytes, err = s.getBytes(etcPath(etcIdentitiesPrefix, id, etcKey)) if err != nil { if err.Error()[0:3] != "100" { return nil, err } // We don't require a key for an identity, so just continue on here } else { i.Key, err = security.KeyFromPEM(pemBytes) if err != nil { return nil, err } } pemBytes, err = s.getBytes(etcPath(etcIdentitiesPrefix, id, etcCertificate)) if err != nil { if err.Error()[0:3] != "100" { return nil, err } } else { i.Certificate, err = security.CertificateFromPEM(pemBytes) if err != nil { return nil, err } } pemBytes, err = s.getBytes(etcPath(etcIdentitiesPrefix, id, etcRequest)) if err != nil { if err.Error()[0:3] != "100" { return nil, err } } else { i.Request, err = security.RequestFromPEM(pemBytes) if err != nil { return nil, err } } // Now check the validitiy of the identity if !i.IsValid() { return nil, nil } return i, nil }
// HandleControlConnection ... func (d *Director) HandleControlConnection(conn net.Conn) { var ( err error cmd byte peerId string startTLS bool ) defer conn.Close() // setup a base logger so all messages include our address logger := log.WithFields(log.Fields{ "address": conn.RemoteAddr().String(), "type": "control", }) logger.Debug("New connection for Control RPC") proto := protocol.NewProtocol(conn) // Announce the protocol logger.Debug("Announcing protocol") if err = proto.Announce(); err != nil { log.WithError(err).Error("Protocol announcement failed") return } logger.Debug("Protocol announced") logger.Debug("Beginning TLS setup") startTLS = false for !startTLS { cmd, err = proto.ReadByte() if err != nil { logger.WithError(err).Error("Failed to read protocol command") return } switch cmd { case protocol.SigningRequest: logger.Debug("Reading signing request") request, err := proto.HandleSigningRequest() if err != nil { logger.WithError(err).Error("Failed to read signing request") return } // get the identity via the common name in the request logger.WithFields(log.Fields{ "name": request.Subject.CommonName, }).Debug("Loading identity") identity, err := d.state.LoadIdentity(request.Subject.CommonName) if err != nil { logger.WithFields(log.Fields{ "error": err, "id": request.Subject.CommonName, }).Error("Error while loading the identity") return } if identity == nil { // Invalid identity, this means we want to create a new identity for an admin to sign logger.WithFields(log.Fields{ "name": request.Subject.CommonName, }).Debug("Creating new identity") identity = security.NewIdentity(request.Subject.CommonName) identity.Request = request d.state.StoreIdentity(identity) d.state.AddIdentityToPending(identity) if err = proto.Ack(); err != nil { logger.WithError(err).Error("Failed to ack signing request") return } } else { // See if this identity has a certificate to send back if identity.Certificate != nil { logger.WithFields(log.Fields{ "name": request.Subject.CommonName, }).Debug("Sending signed certificate") if err = proto.Resp(); err != nil { logger.WithError(err).Error("Failed to signal response") return } proto.SendCertificate(identity.Certificate) proto.SendCertificate(d.authority.Certificate) } else { if err = proto.Ack(); err != nil { logger.WithError(err).Error("Failed to ack signing request") return } logger.WithFields(log.Fields{ "name": request.Subject.CommonName, }).Debug("Request is still pending") } } case protocol.TLS: logger.Info("Upgrading connection to TLS") if peerId, err = proto.HandleStartTLS(d.identity, d.authority.Certificate); err != nil { logger.WithError(err).Error("Failed up handle Start TLS") return } logger.WithFields(log.Fields{ "peerId": peerId, }).Debug("Upgraded!") // Load our identity. We don't actually care about the identity -- we just want to // make sure that it's valid and loads correctly based on this peer ID _, err := d.state.LoadIdentity(peerId) if err != nil { logger.WithError(err).Error("Failed to load Agent Identity") return } startTLS = true default: logger.WithFields(log.Fields{ "cmd": cmd, }).Error("Unknown command") return } } logger.Info("Control connection established, serving RPC") control.ServeConn(proto.Conn(), control.NewRPC(d)) }