func certificateFingerprintDelete(d *Daemon, r *http.Request) Response { fingerprint := mux.Vars(r)["fingerprint"] for i, cert := range d.clientCerts { if fingerprint == shared.GenerateFingerprint(&cert) { fingerprint := shared.GenerateFingerprint(&cert) d.clientCerts = append(d.clientCerts[:i], d.clientCerts[i+1:]...) _, err := dbExec(d.db, "DELETE FROM certificates WHERE fingerprint=?", fingerprint) if err != nil { return SmartError(err) } return EmptySyncResponse } } return NotFound }
func certificatesGet(d *Daemon, r *http.Request) Response { body := []string{} for _, cert := range d.clientCerts { fingerprint := shared.GenerateFingerprint(&cert) body = append(body, fingerprint) } return SyncResponse(true, body) }
func certificateFingerprintGet(d *Daemon, r *http.Request) Response { fingerprint := mux.Vars(r)["fingerprint"] for _, cert := range d.clientCerts { if fingerprint == shared.GenerateFingerprint(&cert) { b64 := base64.StdEncoding.EncodeToString(cert.Raw) body := shared.Jmap{"type": "client", "certificates": b64} return SyncResponse(true, body) } } return NotFound }
func saveCert(d *Daemon, host string, cert *x509.Certificate) error { tx, err := dbBegin(d.db) if err != nil { return err } fingerprint := shared.GenerateFingerprint(cert) stmt, err := tx.Prepare("INSERT INTO certificates (fingerprint,type,name,certificate) VALUES (?, ?, ?, ?)") if err != nil { tx.Rollback() return err } defer stmt.Close() _, err = stmt.Exec(fingerprint, 1, host, pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: cert.Raw})) if err != nil { tx.Rollback() return err } return txCommit(tx) }
func certificatesPost(d *Daemon, r *http.Request) Response { req := certificatesPostBody{} if err := shared.ReadToJSON(r.Body, &req); err != nil { return BadRequest(err) } if req.Type != "client" { return BadRequest(fmt.Errorf("Unknown request type %s", req.Type)) } var cert *x509.Certificate var name string if req.Certificate != "" { data, err := base64.StdEncoding.DecodeString(req.Certificate) if err != nil { return BadRequest(err) } cert, err = x509.ParseCertificate(data) if err != nil { return BadRequest(err) } name = req.Name } else if r.TLS != nil { if len(r.TLS.PeerCertificates) < 1 { return BadRequest(fmt.Errorf("No client certificate provided")) } cert = r.TLS.PeerCertificates[len(r.TLS.PeerCertificates)-1] remoteHost, _, err := net.SplitHostPort(r.RemoteAddr) if err != nil { return InternalError(err) } name = remoteHost } else { return BadRequest(fmt.Errorf("Can't use TLS data on non-TLS link")) } fingerprint := shared.GenerateFingerprint(cert) for _, existingCert := range d.clientCerts { if fingerprint == shared.GenerateFingerprint(&existingCert) { return EmptySyncResponse } } if !d.isTrustedClient(r) && !d.verifyAdminPwd(req.Password) { return Forbidden } err := saveCert(d, name, cert) if err != nil { return SmartError(err) } d.clientCerts = append(d.clientCerts, *cert) return EmptySyncResponse }