📄 sip_security.c
字号:
/* Functions parsing @RFC3329 SIP Security Agreement headers */typedef struct sip_security_agree_s sip_security_agree_t;#define sh_security_agree sh_security_clientstatic int sip_security_agree_d(su_home_t *home, sip_header_t *h, char *s, int slen){ sip_header_t **hh = &h->sh_succ, *h0 = h; sip_security_agree_t *sa = h->sh_security_agree; int n; for (;*s;) { /* Ignore empty entries (comma-whitespace) */ if (*s == ',') { *s++ = '\0'; skip_lws(&s); continue; } if (!h) { /* Allocate next header structure */ if (!(h = sip_header_alloc(home, h0->sh_class, 0))) return -1; *hh = h; h->sh_prev = hh; hh = &h->sh_succ; sa = sa->sa_next = h->sh_security_agree; } sa = h->sh_security_agree; if ((n = span_token(s)) == 0) return -1; sa->sa_mec = s; s += n; while (IS_LWS(*s)) *s++ = '\0'; if (*s == ';' && msg_params_d(home, &s, &sa->sa_params) < 0) return -1; if (*s != '\0' && *s != ',') return -1; if (sa->sa_params) msg_header_update_params(sa->sa_common, 0); h = NULL; } if (h) /* Empty list -> error */ return -1; return 0;}static int sip_security_agree_e(char b[], int bsiz, sip_header_t const *h, int f){ char *end = b + bsiz, *b0 = b; sip_security_agree_t const *sa = h->sh_security_agree; MSG_STRING_E(b, end, sa->sa_mec); MSG_PARAMS_E(b, end, sa->sa_params, flags); return b - b0;}static int sip_security_agree_dup_xtra(sip_header_t const *h, int offset){ sip_security_agree_t const *sa = h->sh_security_agree; MSG_PARAMS_SIZE(offset, sa->sa_params); offset += MSG_STRING_SIZE(sa->sa_mec); return offset;}/** Duplicate one sip_security_agree_t object */ static char *sip_security_agree_dup_one(sip_header_t *dst, sip_header_t const *src, char *b, int xtra){ sip_security_agree_t *sa_dst = dst->sh_security_agree; sip_security_agree_t const *sa_src = src->sh_security_agree; char *end = b + xtra; b = msg_params_dup(&sa_dst->sa_params, sa_src->sa_params, b, xtra); MSG_STRING_DUP(b, sa_dst->sa_mec, sa_src->sa_mec); assert(b <= end); return b;}static int sip_security_agree_update(msg_common_t *h, char const *name, int namelen, char const *value){ sip_security_agree_t *sa = (sip_security_agree_t *)h; if (name == NULL) { sa->sa_q = NULL; sa->sa_d_alg = NULL; sa->sa_d_qop = NULL; sa->sa_d_ver = NULL; }#define MATCH(s) (namelen == strlen(#s) && !strncasecmp(name, #s, strlen(#s))) else if (MATCH(q)) { sa->sa_q = value; } else if (MATCH(d-alg)) { sa->sa_d_alg = value; } else if (MATCH(d-qop)) { sa->sa_d_qop = value; } else if (MATCH(d-ver)) { sa->sa_d_ver = value; }#undef MATCH return 0;}/**@SIP_HEADER sip_security_client Security-Client Header * * The Security-Client header is defined by @RFC3329, "Security Mechanism * Agreement for the Session Initiation Protocol (SIP)". * * @code * security-client = "Security-Client" HCOLON * sec-mechanism *(COMMA sec-mechanism) * security-server = "Security-Server" HCOLON * sec-mechanism *(COMMA sec-mechanism) * security-verify = "Security-Verify" HCOLON * sec-mechanism *(COMMA sec-mechanism) * sec-mechanism = mechanism-name *(SEMI mech-parameters) * mechanism-name = ( "digest" / "tls" / "ipsec-ike" / * "ipsec-man" / token ) * mech-parameters = ( preference / digest-algorithm / * digest-qop / digest-verify / extension ) * preference = "q" EQUAL qvalue * qvalue = ( "0" [ "." 0*3DIGIT ] ) * / ( "1" [ "." 0*3("0") ] ) * digest-algorithm = "d-alg" EQUAL token * digest-qop = "d-qop" EQUAL token * digest-verify = "d-ver" EQUAL LDQUOT 32LHEX RDQUOT * extension = generic-param * @endcode * * @sa sip_security_server, sip_security_verify */msg_hclass_t sip_security_client_class[] = SIP_HEADER_CLASS(security_client, "Security-Client", "", sa_params, append, security_agree);int sip_security_client_d(su_home_t *home, sip_header_t *h, char *s, int slen){ return sip_security_agree_d(home, h, s, slen);}int sip_security_client_e(char b[], int bsiz, sip_header_t const *h, int f){ return sip_security_agree_e(b, bsiz, h, f);}/**@SIP_HEADER sip_security_server Security-Server Header * * The Security-Server header is defined by @RFC3329, "Security Mechanism * Agreement for the Session Initiation Protocol (SIP)". * * @sa sip_security_client, sip_security_verify */msg_hclass_t sip_security_server_class[] = SIP_HEADER_CLASS(security_server, "Security-Server", "", sa_params, append, security_agree);int sip_security_server_d(su_home_t *home, sip_header_t *h, char *s, int slen){ return sip_security_agree_d(home, h, s, slen);}int sip_security_server_e(char b[], int bsiz, sip_header_t const *h, int f){ return sip_security_agree_e(b, bsiz, h, f);}/**@SIP_HEADER sip_security_verify Security-Verify Header * * The Security-Verify header is defined by @RFC3329, "Security Mechanism * Agreement for the Session Initiation Protocol (SIP)". * * @sa sip_security_client, sip_security_server */msg_hclass_t sip_security_verify_class[] = SIP_HEADER_CLASS(security_verify, "Security-Verify", "", sa_params, append, security_agree);int sip_security_verify_d(su_home_t *home, sip_header_t *h, char *s, int slen){ return sip_security_agree_d(home, h, s, slen);}int sip_security_verify_e(char b[], int bsiz, sip_header_t const *h, int f){ return sip_security_agree_e(b, bsiz, h, f);}/* ====================================================================== *//* RFC 3323 *//**@SIP_HEADER sip_privacy Privacy Header * * The Privacy header is used by User-Agent to request privacy services from * the network. Its syntax is defined in [RFC3323] as follows: * * @code * Privacy-hdr = "Privacy" HCOLON priv-value *(";" priv-value) * priv-value = "header" / "session" / "user" / "none" / "critical" * / token * @endcode */msg_xtra_f sip_privacy_dup_xtra;msg_dup_f sip_privacy_dup_one;#define sip_privacy_update NULLmsg_hclass_t sip_privacy_class[] = SIP_HEADER_CLASS(privacy, "Privacy", "", priv_values, single, privacy);static int sip_privacy_token_scan(char *start){ char *s = start; skip_token(&s); if (s == start) return -1; if (IS_LWS(*s)) *s++ = '\0'; skip_lws(&s); return s - start;}int sip_privacy_d(su_home_t *home, sip_header_t *h, char *s, int slen){ sip_privacy_t *priv = h->sh_privacy; while (*s == ';' || *s == ',') { s++; skip_lws(&s); } for (;;) { if (msg_any_list_d(home, &s, (msg_param_t **)&priv->priv_values, sip_privacy_token_scan, ';') < 0) return -1; if (*s == '\0') return 0; /* Success! */ if (*s == ',') *s++ = '\0'; /* We accept comma-separated list, too */ else if (IS_TOKEN(*s)) ; /* LWS separated list... */ else return -1; }}int sip_privacy_e(char b[], int bsiz, sip_header_t const *h, int f){ sip_privacy_t const *priv = h->sh_privacy; char *b0 = b, *end = b + bsiz; int i; if (priv->priv_values) { for (i = 0; priv->priv_values[i]; i++) { if (i > 0) MSG_CHAR_E(b, end, ';'); MSG_STRING_E(b, end, priv->priv_values[i]); } } MSG_TERM_E(b, end); return b - b0;}int sip_privacy_dup_xtra(sip_header_t const *h, int offset){ sip_privacy_t const *priv = h->sh_privacy; MSG_PARAMS_SIZE(offset, priv->priv_values); return offset;}char *sip_privacy_dup_one(sip_header_t *dst, sip_header_t const *src, char *b, int xtra){ sip_privacy_t *priv = dst->sh_privacy; sip_privacy_t const *o = src->sh_privacy; char *end = b + xtra; b = msg_params_dup(&priv->priv_values, o->priv_values, b, xtra); assert(b <= end); return b;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -