Add notion of `ephemeral' associations and a goodbye protocol.
[tripe] / server / tripe.h
index 494aa18..a2907be 100644 (file)
@@ -402,6 +402,7 @@ struct algswitch {
 struct kdata {
   unsigned ref;                                /* Reference counter */
   struct knode *kn;                    /* Pointer to cache entry */
+  uint32 id;                           /* The underlying key's id */
   char *tag;                           /* Full tag name of the key */
   dhgrp *grp;                          /* The group we work in */
   dhsc *k;                             /* The private key (or null) */
@@ -609,12 +610,14 @@ typedef struct peerspec {
   char *name;                          /* Peer's name */
   char *privtag;                       /* Private key tag */
   char *tag;                           /* Public key tag */
+  char *knock;                         /* Knock string, or null */
   const tunnel_ops *tops;              /* Tunnel operations */
   unsigned long t_ka;                  /* Keep alive interval */
   addr sa;                             /* Socket address to speak to */
   unsigned f;                          /* Flags for the peer */
 #define PSF_KXMASK 255u                        /*   Key-exchange flags to set */
 #define PSF_MOBILE 256u                        /*   Address may change rapidly */
+#define PSF_EPHEM 512u                 /*   Association is ephemeral */
 } peerspec;
 
 typedef struct peer_byname {
@@ -827,6 +830,19 @@ extern int km_reload(void);
 extern kdata *km_findpub(const char */*tag*/);
 extern kdata *km_findpriv(const char */*tag*/);
 
+/* --- @km_findpubbyid@, @km_findprivbyid@ --- *
+ *
+ * Arguments:  @uint32 id@ = key id to load
+ *
+ * Returns:    Pointer to the kdata object if successful, or null on error.
+ *
+ * Use:                Fetches a public or private key from the keyring given its
+ *             numeric id.
+ */
+
+extern kdata *km_findpubbyid(uint32 /*id*/);
+extern kdata *km_findprivbyid(uint32 /*id*/);
+
 /* --- @km_samealgsp@ --- *
  *
  * Arguments:  @const kdata *kdx, *kdy@ = two key data objects
@@ -889,16 +905,18 @@ extern void kx_start(keyexch */*kx*/, int /*forcep*/);
 /* --- @kx_message@ --- *
  *
  * Arguments:  @keyexch *kx@ = pointer to key exchange context
+ *             @const addr *a@ = sender's IP address and port
  *             @unsigned msg@ = the message code
  *             @buf *b@ = pointer to buffer containing the packet
  *
- * Returns:    ---
+ * Returns:    Nonzero if the sender's address was unknown.
  *
  * Use:                Reads a packet containing key exchange messages and handles
  *             it.
  */
 
-extern void kx_message(keyexch */*kx*/, unsigned /*msg*/, buf */*b*/);
+extern int kx_message(keyexch */*kx*/, const addr */*a*/,
+                     unsigned /*msg*/, buf */*b*/);
 
 /* --- @kx_free@ --- *
  *
@@ -942,6 +960,17 @@ extern void kx_newkeys(keyexch */*kx*/);
 extern int kx_setup(keyexch */*kx*/, peer */*p*/,
                    keyset **/*ks*/, unsigned /*f*/);
 
+/* --- @kx_init@ --- *
+ *
+ * Arguments:  ---
+ *
+ * Returns:    ---
+ *
+ * Use:                Initializes the key-exchange logic.
+ */
+
+extern void kx_init(void);
+
 /*----- Keysets and symmetric cryptography --------------------------------*/
 
 /* --- @ks_drop@ --- *
@@ -1427,6 +1456,20 @@ extern int p_updateaddr(peer */*p*/, const addr */*a*/);
 
 extern buf *p_txstart(peer */*p*/, unsigned /*msg*/);
 
+/* --- @p_txaddr@ --- *
+ *
+ * Arguments:  @const addr *a@ = recipient address
+ *             @const void *p@ = pointer to packet to send
+ *             @size_t sz@ = length of packet
+ *
+ * Returns:    Zero if successful, nonzero on error.
+ *
+ * Use:                Sends a packet to an address which (possibly) isn't a current
+ *             peer.
+ */
+
+extern int p_txaddr(const addr */*a*/, const void */*p*/, size_t /*sz*/);
+
 /* --- @p_txend@ --- *
  *
  * Arguments:  @peer *p@ = pointer to peer block
@@ -1651,13 +1694,14 @@ extern peer *p_find(const char */*name*/);
 /* --- @p_destroy@ --- *
  *
  * Arguments:  @peer *p@ = pointer to a peer
+ *             @int bye@ = say goodbye to the peer?
  *
  * Returns:    ---
  *
  * Use:                Destroys a peer.
  */
 
-extern void p_destroy(peer */*p*/);
+extern void p_destroy(peer */*p*/, int /*bye*/);
 
 /* --- @FOREACH_PEER@ --- *
  *
@@ -1768,6 +1812,75 @@ extern void seq_reset(seqwin */*s*/);
 
 extern int seq_check(seqwin */*s*/, uint32 /*q*/, const char */*service*/);
 
+typedef struct ratelim {
+  unsigned n, max, persec;
+  struct timeval when;
+} ratelim;
+
+/* --- @ratelim_init@ --- *
+ *
+ * Arguments:  @ratelim *r@ = rate-limiting state to fill in
+ *             @unsigned persec@ = credit to accumulate per second
+ *             @unsigned max@ = maximum credit to retain
+ *
+ * Returns:    ---
+ *
+ * Use:                Initialize a rate-limiting state.
+ */
+
+extern void ratelim_init(ratelim */*r*/,
+                        unsigned /*persec*/, unsigned /*max*/);
+
+/* --- @ratelim_withdraw@ --- *
+ *
+ * Arguments:  @ratelim *r@ = rate-limiting state
+ *             @unsigned n@ = credit to withdraw
+ *
+ * Returns:    Zero if successful; @-1@ if there is unsufficient credit
+ *
+ * Use:                Updates the state with any accumulated credit.  Then, if
+ *             there there are more than @n@ credits available, withdraw @n@
+ *             and return successfully; otherwise, report failure.
+ */
+
+extern int ratelim_withdraw(ratelim */*r*/, unsigned /*n*/);
+
+/* --- @ies_encrypt@ --- *
+ *
+ * Arguments:  @kdata *kpub@ = recipient's public key
+ *             @unsigned ty@ = message type octet
+ *             @buf *b@ = input message buffer
+ *             @buf *bb@ = output buffer for the ciphertext
+ *
+ * Returns:    On error, returns a @KSERR_...@ code or breaks the buffer;
+ *             on success, returns zero and the buffer is good.
+ *
+ * Use:                Encrypts a message for a recipient, given their public key.
+ *             This does not (by itself) provide forward secrecy or sender
+ *             authenticity.  The ciphertext is self-delimiting (unlike
+ *             @ks_encrypt@).
+ */
+
+extern int ies_encrypt(kdata */*kpub*/, unsigned /*ty*/,
+                      buf */*b*/, buf */*bb*/);
+
+/* --- @ies_decrypt@ --- *
+ *
+ * Arguments:  @kdata *kpub@ = private key key
+ *             @unsigned ty@ = message type octet
+ *             @buf *b@ = input ciphertext buffer
+ *             @buf *bb@ = output buffer for the message
+ *
+ * Returns:    On error, returns a @KSERR_...@ code; on success, returns
+ *             zero and the buffer is good.
+ *
+ * Use:                Decrypts a message encrypted using @ies_encrypt@, given our
+ *             private key.
+ */
+
+extern int ies_decrypt(kdata */*kpriv*/, unsigned /*ty*/,
+                      buf */*b*/, buf */*bb*/);
+
 /*----- That's all, folks -------------------------------------------------*/
 
 #ifdef __cplusplus