Example #1
0
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
}
Example #2
0
// 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
}
Example #3
0
// 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))
}