sendProveAttachment asks the peer to prove they have the attachment, without actually sending it. This is to prevent clients from creating a doc with a digest for an attachment they otherwise can't access, in order to download it.
(sender *blip.Sender, docID, name, digest string, knownData []byte)
| 1585 | // sendProveAttachment asks the peer to prove they have the attachment, without actually sending it. |
| 1586 | // This is to prevent clients from creating a doc with a digest for an attachment they otherwise can't access, in order to download it. |
| 1587 | func (bh *blipHandler) sendProveAttachment(sender *blip.Sender, docID, name, digest string, knownData []byte) error { |
| 1588 | base.DebugfCtx(bh.loggingCtx, base.KeySync, " Verifying attachment %q for doc %s (digest %s)", base.UD(name), base.UD(docID), digest) |
| 1589 | nonce, proof, err := GenerateProofOfAttachment(bh.loggingCtx, knownData) |
| 1590 | if err != nil { |
| 1591 | return err |
| 1592 | } |
| 1593 | outrq := blip.NewRequest() |
| 1594 | outrq.SetProfile(MessageProveAttachment) |
| 1595 | outrq.Properties[ProveAttachmentDigest] = digest |
| 1596 | if bh.collectionIdx != nil { |
| 1597 | outrq.Properties[BlipCollection] = strconv.Itoa(*bh.collectionIdx) |
| 1598 | } |
| 1599 | outrq.SetBody(nonce) |
| 1600 | if !bh.sendBLIPMessage(sender, outrq) { |
| 1601 | return ErrClosedBLIPSender |
| 1602 | } |
| 1603 | |
| 1604 | resp := outrq.Response() |
| 1605 | |
| 1606 | body, err := resp.Body() |
| 1607 | if err != nil { |
| 1608 | base.WarnfCtx(bh.loggingCtx, "Error returned for proveAttachment message for doc %s (digest %s). Error: %v", base.UD(docID), digest, err) |
| 1609 | return err |
| 1610 | } |
| 1611 | |
| 1612 | if resp.Type() == blip.ErrorType && |
| 1613 | resp.Properties[BlipErrorDomain] == blip.BLIPErrorDomain && |
| 1614 | resp.Properties[BlipErrorCode] == "404" { |
| 1615 | return errNoBlipHandler |
| 1616 | } |
| 1617 | |
| 1618 | if resp.Type() == blip.ErrorType && |
| 1619 | errorDomainIsHTTP(resp) && |
| 1620 | resp.Properties[BlipErrorCode] == "404" { |
| 1621 | return ErrAttachmentNotFound |
| 1622 | } |
| 1623 | |
| 1624 | if string(body) != proof { |
| 1625 | base.WarnfCtx(bh.loggingCtx, "Incorrect proof for attachment %s : I sent nonce %x, expected proof %q, got %q", digest, base.MD(nonce), base.MD(proof), base.MD(string(body))) |
| 1626 | return base.HTTPErrorf(http.StatusForbidden, "Incorrect proof for attachment %s", digest) |
| 1627 | } |
| 1628 | |
| 1629 | bh.replicationStats.ProveAttachment.Add(1) |
| 1630 | |
| 1631 | base.InfofCtx(bh.loggingCtx, base.KeySync, "proveAttachment successful for doc %s (digest %s)", base.UD(docID), digest) |
| 1632 | return nil |
| 1633 | } |
| 1634 | |
| 1635 | // For each attachment in the revision, makes sure it's in the database, asking the client to |
| 1636 | // upload it if necessary. This method blocks until all the attachments have been processed. |
no test coverage detected