123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322 |
- /* Copyright (c) 2016-2017, The Tor Project, Inc. */
- /* See LICENSE for licensing information */
- /**
- * \file parsecommon.h
- * \brief Header file for parsecommon.c
- **/
- #ifndef TOR_PARSECOMMON_H
- #define TOR_PARSECOMMON_H
- #include "container.h"
- #include "crypto.h"
- #include "memarea.h"
- /** Enumeration of possible token types. The ones starting with K_ correspond
- * to directory 'keywords'. A_ is for an annotation, R or C is related to
- * hidden services, ERR_ is an error in the tokenizing process, EOF_ is an
- * end-of-file marker, and NIL_ is used to encode not-a-token.
- */
- typedef enum {
- K_ACCEPT = 0,
- K_ACCEPT6,
- K_DIRECTORY_SIGNATURE,
- K_RECOMMENDED_SOFTWARE,
- K_REJECT,
- K_REJECT6,
- K_ROUTER,
- K_SIGNED_DIRECTORY,
- K_SIGNING_KEY,
- K_ONION_KEY,
- K_ONION_KEY_NTOR,
- K_ROUTER_SIGNATURE,
- K_PUBLISHED,
- K_RUNNING_ROUTERS,
- K_ROUTER_STATUS,
- K_PLATFORM,
- K_PROTO,
- K_OPT,
- K_BANDWIDTH,
- K_CONTACT,
- K_NETWORK_STATUS,
- K_UPTIME,
- K_DIR_SIGNING_KEY,
- K_FAMILY,
- K_FINGERPRINT,
- K_HIBERNATING,
- K_READ_HISTORY,
- K_WRITE_HISTORY,
- K_NETWORK_STATUS_VERSION,
- K_DIR_SOURCE,
- K_DIR_OPTIONS,
- K_CLIENT_VERSIONS,
- K_SERVER_VERSIONS,
- K_RECOMMENDED_CLIENT_PROTOCOLS,
- K_RECOMMENDED_RELAY_PROTOCOLS,
- K_REQUIRED_CLIENT_PROTOCOLS,
- K_REQUIRED_RELAY_PROTOCOLS,
- K_OR_ADDRESS,
- K_ID,
- K_P,
- K_P6,
- K_R,
- K_A,
- K_S,
- K_V,
- K_W,
- K_M,
- K_EXTRA_INFO,
- K_EXTRA_INFO_DIGEST,
- K_CACHES_EXTRA_INFO,
- K_HIDDEN_SERVICE_DIR,
- K_ALLOW_SINGLE_HOP_EXITS,
- K_IPV6_POLICY,
- K_ROUTER_SIG_ED25519,
- K_IDENTITY_ED25519,
- K_MASTER_KEY_ED25519,
- K_ONION_KEY_CROSSCERT,
- K_NTOR_ONION_KEY_CROSSCERT,
- K_DIRREQ_END,
- K_DIRREQ_V2_IPS,
- K_DIRREQ_V3_IPS,
- K_DIRREQ_V2_REQS,
- K_DIRREQ_V3_REQS,
- K_DIRREQ_V2_SHARE,
- K_DIRREQ_V3_SHARE,
- K_DIRREQ_V2_RESP,
- K_DIRREQ_V3_RESP,
- K_DIRREQ_V2_DIR,
- K_DIRREQ_V3_DIR,
- K_DIRREQ_V2_TUN,
- K_DIRREQ_V3_TUN,
- K_ENTRY_END,
- K_ENTRY_IPS,
- K_CELL_END,
- K_CELL_PROCESSED,
- K_CELL_QUEUED,
- K_CELL_TIME,
- K_CELL_CIRCS,
- K_EXIT_END,
- K_EXIT_WRITTEN,
- K_EXIT_READ,
- K_EXIT_OPENED,
- K_DIR_KEY_CERTIFICATE_VERSION,
- K_DIR_IDENTITY_KEY,
- K_DIR_KEY_PUBLISHED,
- K_DIR_KEY_EXPIRES,
- K_DIR_KEY_CERTIFICATION,
- K_DIR_KEY_CROSSCERT,
- K_DIR_ADDRESS,
- K_DIR_TUNNELLED,
- K_VOTE_STATUS,
- K_VALID_AFTER,
- K_FRESH_UNTIL,
- K_VALID_UNTIL,
- K_VOTING_DELAY,
- K_KNOWN_FLAGS,
- K_PARAMS,
- K_BW_WEIGHTS,
- K_VOTE_DIGEST,
- K_CONSENSUS_DIGEST,
- K_ADDITIONAL_DIGEST,
- K_ADDITIONAL_SIGNATURE,
- K_CONSENSUS_METHODS,
- K_CONSENSUS_METHOD,
- K_LEGACY_DIR_KEY,
- K_DIRECTORY_FOOTER,
- K_SIGNING_CERT_ED,
- K_SR_FLAG,
- K_COMMIT,
- K_PREVIOUS_SRV,
- K_CURRENT_SRV,
- K_PACKAGE,
- A_PURPOSE,
- A_LAST_LISTED,
- A_UNKNOWN_,
- R_RENDEZVOUS_SERVICE_DESCRIPTOR,
- R_VERSION,
- R_PERMANENT_KEY,
- R_SECRET_ID_PART,
- R_PUBLICATION_TIME,
- R_PROTOCOL_VERSIONS,
- R_INTRODUCTION_POINTS,
- R_SIGNATURE,
- R_HS_DESCRIPTOR, /* From version 3, this MUST be generic to all future
- descriptor versions thus making it R_. */
- R3_DESC_LIFETIME,
- R3_DESC_SIGNING_CERT,
- R3_REVISION_COUNTER,
- R3_SUPERENCRYPTED,
- R3_SIGNATURE,
- R3_CREATE2_FORMATS,
- R3_INTRO_AUTH_REQUIRED,
- R3_SINGLE_ONION_SERVICE,
- R3_INTRODUCTION_POINT,
- R3_INTRO_ONION_KEY,
- R3_INTRO_AUTH_KEY,
- R3_INTRO_ENC_KEY,
- R3_INTRO_ENC_KEY_CERT,
- R3_INTRO_LEGACY_KEY,
- R3_INTRO_LEGACY_KEY_CERT,
- R3_DESC_AUTH_TYPE,
- R3_DESC_AUTH_KEY,
- R3_DESC_AUTH_CLIENT,
- R3_ENCRYPTED,
- R_IPO_IDENTIFIER,
- R_IPO_IP_ADDRESS,
- R_IPO_ONION_PORT,
- R_IPO_ONION_KEY,
- R_IPO_SERVICE_KEY,
- C_CLIENT_NAME,
- C_DESCRIPTOR_COOKIE,
- C_CLIENT_KEY,
- ERR_,
- EOF_,
- NIL_
- } directory_keyword;
- /** Structure to hold a single directory token.
- *
- * We parse a directory by breaking it into "tokens", each consisting
- * of a keyword, a line full of arguments, and a binary object. The
- * arguments and object are both optional, depending on the keyword
- * type.
- *
- * This structure is only allocated in memareas; do not allocate it on
- * the heap, or token_clear() won't work.
- */
- typedef struct directory_token_t {
- directory_keyword tp; /**< Type of the token. */
- int n_args:30; /**< Number of elements in args */
- char **args; /**< Array of arguments from keyword line. */
- char *object_type; /**< -----BEGIN [object_type]-----*/
- size_t object_size; /**< Bytes in object_body */
- char *object_body; /**< Contents of object, base64-decoded. */
- crypto_pk_t *key; /**< For public keys only. Heap-allocated. */
- char *error; /**< For ERR_ tokens only. */
- } directory_token_t;
- /** We use a table of rules to decide how to parse each token type. */
- /** Rules for whether the keyword needs an object. */
- typedef enum {
- NO_OBJ, /**< No object, ever. */
- NEED_OBJ, /**< Object is required. */
- NEED_SKEY_1024,/**< Object is required, and must be a 1024 bit private key */
- NEED_KEY_1024, /**< Object is required, and must be a 1024 bit public key */
- NEED_KEY, /**< Object is required, and must be a public key. */
- OBJ_OK, /**< Object is optional. */
- } obj_syntax;
- #define AT_START 1
- #define AT_END 2
- #define TS_ANNOTATIONS_OK 1
- #define TS_NOCHECK 2
- #define TS_NO_NEW_ANNOTATIONS 4
- /**
- * @name macros for defining token rules
- *
- * Helper macros to define token tables. 's' is a string, 't' is a
- * directory_keyword, 'a' is a trio of argument multiplicities, and 'o' is an
- * object syntax.
- */
- /**@{*/
- /** Appears to indicate the end of a table. */
- #define END_OF_TABLE { NULL, NIL_, 0,0,0, NO_OBJ, 0, INT_MAX, 0, 0 }
- /** An item with no restrictions: used for obsolete document types */
- #define T(s,t,a,o) { s, t, a, o, 0, INT_MAX, 0, 0 }
- /** An item with no restrictions on multiplicity or location. */
- #define T0N(s,t,a,o) { s, t, a, o, 0, INT_MAX, 0, 0 }
- /** An item that must appear exactly once */
- #define T1(s,t,a,o) { s, t, a, o, 1, 1, 0, 0 }
- /** An item that must appear exactly once, at the start of the document */
- #define T1_START(s,t,a,o) { s, t, a, o, 1, 1, AT_START, 0 }
- /** An item that must appear exactly once, at the end of the document */
- #define T1_END(s,t,a,o) { s, t, a, o, 1, 1, AT_END, 0 }
- /** An item that must appear one or more times */
- #define T1N(s,t,a,o) { s, t, a, o, 1, INT_MAX, 0, 0 }
- /** An item that must appear no more than once */
- #define T01(s,t,a,o) { s, t, a, o, 0, 1, 0, 0 }
- /** An annotation that must appear no more than once */
- #define A01(s,t,a,o) { s, t, a, o, 0, 1, 0, 1 }
- /** Argument multiplicity: any number of arguments. */
- #define ARGS 0,INT_MAX,0
- /** Argument multiplicity: no arguments. */
- #define NO_ARGS 0,0,0
- /** Argument multiplicity: concatenate all arguments. */
- #define CONCAT_ARGS 1,1,1
- /** Argument multiplicity: at least <b>n</b> arguments. */
- #define GE(n) n,INT_MAX,0
- /** Argument multiplicity: exactly <b>n</b> arguments. */
- #define EQ(n) n,n,0
- /**@}*/
- /** Determines the parsing rules for a single token type. */
- typedef struct token_rule_t {
- /** The string value of the keyword identifying the type of item. */
- const char *t;
- /** The corresponding directory_keyword enum. */
- directory_keyword v;
- /** Minimum number of arguments for this item */
- int min_args;
- /** Maximum number of arguments for this item */
- int max_args;
- /** If true, we concatenate all arguments for this item into a single
- * string. */
- int concat_args;
- /** Requirements on object syntax for this item. */
- obj_syntax os;
- /** Lowest number of times this item may appear in a document. */
- int min_cnt;
- /** Highest number of times this item may appear in a document. */
- int max_cnt;
- /** One or more of AT_START/AT_END to limit where the item may appear in a
- * document. */
- int pos;
- /** True iff this token is an annotation. */
- int is_annotation;
- } token_rule_t;
- void token_clear(directory_token_t *tok);
- int tokenize_string(memarea_t *area,
- const char *start, const char *end,
- smartlist_t *out,
- token_rule_t *table,
- int flags);
- directory_token_t *get_next_token(memarea_t *area,
- const char **s,
- const char *eos,
- token_rule_t *table);
- directory_token_t *find_by_keyword_(smartlist_t *s,
- directory_keyword keyword,
- const char *keyword_str);
- #define find_by_keyword(s, keyword) \
- find_by_keyword_((s), (keyword), #keyword)
- directory_token_t *find_opt_by_keyword(const smartlist_t *s,
- directory_keyword keyword);
- smartlist_t * find_all_by_keyword(const smartlist_t *s, directory_keyword k);
- #endif /* !defined(TOR_PARSECOMMON_H) */
|