Beispiel #1
0
/*
 * sdp_debug_msg_filter
 *
 * DESCRIPTION
 *     Check the passed message buffer for sensitive data that should
 *     not be output (such as SRTP Master Key/Salt). Sensitive data
 *     will be replaced with the '*' character(s).
 *
 * PARAMETERS
 *     buffer: pointer to the message buffer to filter.
 *
 *     length_bytes: size of message buffer in bytes.
 *
 * RETURN VALUE
 *     The buffer modified.
 */
char * sdp_debug_msg_filter (char *buffer, ulong length_bytes)
{
    char *current;
    char *last = buffer + length_bytes;
    int result;

    SDP_PRINT("\n%s:%d: Eliding sensitive data from debug output",
            __FILE__, __LINE__);
    /*
     * For SRTP Master Key/Salt has the form:
     * X-crypto:<crypto_suite_name> inline:<master_key_salt>||
     * Where <master_key_salt> is the data to elide (filter).
     */
    for (current=buffer;
         current<=last-MIN_CRYPTO_STRING_SIZE_BYTES;
         current++) {
        if ((*current == 'x') || (*current == 'X')) {
            result = cpr_strncasecmp(current, crypto_string, crypto_strlen);
            if (!result) {
                current += crypto_strlen;
                if (current > last) break;

                /* Skip over crypto suite name */
                FIND_WHITESPACE(current, last);

                /* Skip over whitespace */
                SKIP_WHITESPACE(current, last);

                /* identify inline keyword */
                result = cpr_strncasecmp(current, inline_string, inline_strlen);
                if (!result) {
                    current += inline_strlen;
                    if (current > last) break;

                    /* Hide sensitive key/salt data */
                    while (current<=last) {
                        if (*current == '|' || *current == '\n') {
                            /* Done */
                            break;
                        } else {
                            *current = '*';
                            current++;
                        }
                    }
                }
            }
        }
    }

    return buffer;
}
Beispiel #2
0
/*
 * ccsip_decode_call_info_hdr
 *
 * Description:
 *
 * Main method which decodes a single call info header and stores the
 * related parms.
 *
 * Example Input:
 * ---------------
 * <urn:x-cisco-remotecc:hold>; reason= conference
 * <urn:x-cisco-remotecc:callinfo>; seCuRity=unsecure; orienTation= to
 */
static void
ccsip_decode_call_info_hdr (const char *call_info_hdr_p,
                            cc_call_info_t *call_info_p)
{
    char           *ptr = NULL;
    char           *laq_ptr = NULL;
    char           *raq_ptr = NULL;
    boolean         ret_val = FALSE;
    char            feat_string[FEAT_STRING_SIZE];

    memset(feat_string, '\0', sizeof(feat_string));

    /*
     * call_info_hdr_p and call_info_p are verified by caller so they
     * are not checked here.
     */

    ptr = laq_ptr = strchr(call_info_hdr_p, LAQUOT);
    raq_ptr = strchr(call_info_hdr_p, RAQUOT);

    // Parse out the remotecc string and the feature string.
    if (laq_ptr && raq_ptr) {
        ptr++;

        // Verify the remotecc string.
        if (!cpr_strncasecmp(ptr, URN_REMOTECC, sizeof(URN_REMOTECC) - 1)) {
            ptr += sizeof(URN_REMOTECC) - 1;
            sstrncpy(feat_string, ptr, raq_ptr - ptr + 1);

            // Which feature do we have in this header?
            call_info_p->type = which_feature(feat_string);

            if (call_info_p->type != CC_FEAT_NONE) {
                ret_val = TRUE;
                set_parm_defaults(call_info_p);
            }
        }
    }

    if (!ret_val) {
        return;
    }

    if (!(ptr = strchr(raq_ptr, SEMI_COLON))) {
        return;
    }

    switch (call_info_p->type) {
    case CC_FEAT_CALLINFO:
        parse_call_info_parm(ptr, &call_info_p->data);
        break;
    default:
        parse_gen_parm(ptr, &call_info_p->data);
    }
}
Beispiel #3
0
/*
 * parse_gen_parm
 *
 * Description:
 *
 * Parse feature parms where the only expected parm is the purpose.
 */
static void
parse_gen_parm (char *parm_p, cc_call_info_data_t * feature_data_p)
{
    if (!parm_p)
        return;

    while (parm_p) {
        parm_p++;
        SKIP_LWS(parm_p);

        if (!cpr_strncasecmp(parm_p, SIP_CI_GENERIC,
                             sizeof(SIP_CI_GENERIC) - 1)) {
            parm_p = parm_p + sizeof(SIP_CI_GENERIC) - 1;
            SKIP_LWS(parm_p);

            if (*parm_p) {
                if (!cpr_strncasecmp(parm_p, SIP_CI_GENERIC_ICON,
                                     sizeof(SIP_CI_GENERIC_ICON) - 1)) {
                    feature_data_p->purpose = CC_PURPOSE_ICON;
                } else {
                    if (!cpr_strncasecmp(parm_p, SIP_CI_GENERIC_INFO,
                                         sizeof(SIP_CI_GENERIC_INFO) - 1)) {
                        feature_data_p->purpose = CC_PURPOSE_INFO;
                    } else {
                        if (!cpr_strncasecmp(parm_p, SIP_CI_GENERIC_CARD,
                                             sizeof(SIP_CI_GENERIC_CARD) - 1)) {
                            feature_data_p->purpose = CC_PURPOSE_CARD;
                        }
                    }
                }
            }
        } else {
            break;
        }
        parm_p = strchr(parm_p, SEMI_COLON);
    }
}
Beispiel #4
0
/*
 * parse_call_info_parm
 *
 * Description:
 *
 * Parse potential callinfo feature parms.
 */
static void
parse_call_info_parm (char *parm_p, cc_call_info_data_t * feature_data_p)
{
    static const char fname[] = "parse_call_info_parm";
    char *temp_p;
    uint16_t instance_id;
    unsigned long strtoul_result;
    char *strtoul_end;

    if (!parm_p)
        return;

    while (parm_p) {
        parm_p++;
        SKIP_LWS(parm_p);

        if (!cpr_strncasecmp(parm_p, SIP_CI_SECURITY,
                             sizeof(SIP_CI_SECURITY) - 1)) {
            parm_p = parm_p + sizeof(SIP_CI_SECURITY) - 1;
            SKIP_LWS(parm_p);

            if (*parm_p) {
                feature_data_p->call_info_feat_data.feature_flag |= CC_SECURITY;
                if (!cpr_strncasecmp(parm_p, SIP_CI_SECURITY_UNKNOWN,
                                     sizeof(SIP_CI_SECURITY_UNKNOWN) - 1)) {
                    feature_data_p->call_info_feat_data.security = CC_SECURITY_UNKNOWN;
                } else if (!cpr_strncasecmp(parm_p, SIP_CI_SECURITY_AUTH,
                                         sizeof(SIP_CI_SECURITY_AUTH) - 1)) {
                    feature_data_p->call_info_feat_data.security = CC_SECURITY_AUTHENTICATED;
                } else if (!cpr_strncasecmp(parm_p, SIP_CI_SECURITY_ENCRYPTED,
                                         sizeof(SIP_CI_SECURITY_ENCRYPTED) - 1)) {
                    feature_data_p->call_info_feat_data.security = CC_SECURITY_ENCRYPTED;
                } else if (!cpr_strncasecmp(parm_p, SIP_CI_SECURITY_NOT_AUTH,
                                             sizeof(SIP_CI_SECURITY_NOT_AUTH) - 1)) {
                    feature_data_p->call_info_feat_data.security = CC_SECURITY_NOT_AUTHENTICATED;
                } else {
                            CCSIP_DEBUG_ERROR(SIP_F_PREFIX "Unknown security"
                                              " value %s\n", fname, parm_p);
                    feature_data_p->call_info_feat_data.security = CC_SECURITY_UNKNOWN;
                }
            } else {
                break;
            }
        } else if (!cpr_strncasecmp(parm_p, SIP_CI_POLICY,
			sizeof(SIP_CI_POLICY) - 1)) {
	    parm_p = parm_p + sizeof(SIP_CI_POLICY) - 1;
	    SKIP_LWS(parm_p);

	    if (*parm_p) {
		feature_data_p->call_info_feat_data.feature_flag |= CC_POLICY;
		if (!cpr_strncasecmp(parm_p, SIP_CI_POLICY_CHAPERONE ,
				sizeof(SIP_CI_POLICY_CHAPERONE) - 1)) {
		    feature_data_p->call_info_feat_data.policy = CC_POLICY_CHAPERONE;
		} else if (!cpr_strncasecmp(parm_p, SIP_CI_POLICY_UNKNOWN,
				sizeof(SIP_CI_POLICY_UNKNOWN) - 1)) {
		    feature_data_p->call_info_feat_data.policy = CC_POLICY_UNKNOWN;
		} else {
		    CCSIP_DEBUG_ERROR("%s ERROR: Unknown policy"
			" value %s\n", fname, parm_p) ;
		    feature_data_p->call_info_feat_data.policy = CC_POLICY_UNKNOWN;
		}
	    } else {
		break;
	    }
       	} else if (!cpr_strncasecmp(parm_p, SIP_CI_ORIENTATION,
                                    sizeof(SIP_CI_ORIENTATION) - 1)) {
            parm_p = parm_p + sizeof(SIP_CI_ORIENTATION) - 1;
            SKIP_LWS(parm_p);

            if (*parm_p) {
                feature_data_p->call_info_feat_data.feature_flag |= CC_ORIENTATION;
                if (!cpr_strncasecmp(parm_p, SIP_CI_ORIENTATION_FROM,
                                     sizeof(SIP_CI_ORIENTATION_FROM) - 1)) {
                    feature_data_p->call_info_feat_data.orientation = CC_ORIENTATION_FROM;
                } else if (!cpr_strncasecmp(parm_p, SIP_CI_ORIENTATION_TO,
                                         sizeof(SIP_CI_ORIENTATION_TO) - 1)) {
                    feature_data_p->call_info_feat_data.orientation = CC_ORIENTATION_TO;
                } else {
                    CCSIP_DEBUG_ERROR(SIP_F_PREFIX  "Unknown orientation info"
                                      " value %s\n", fname, parm_p);
                    feature_data_p->call_info_feat_data.orientation = CC_ORIENTATION_NONE;
                }
            } else {
                break;
            }
        } else if (!cpr_strncasecmp(parm_p, SIP_CI_UI_STATE,
                                    sizeof(SIP_CI_UI_STATE) - 1)) {
            parm_p = parm_p + sizeof(SIP_CI_UI_STATE) - 1;
            SKIP_LWS(parm_p);

            if (*parm_p) {
                feature_data_p->call_info_feat_data.feature_flag |= CC_UI_STATE;
                if (!cpr_strncasecmp(parm_p, SIP_CI_UI_STATE_RINGOUT,
                                     sizeof(SIP_CI_UI_STATE_RINGOUT) - 1)) {
                    feature_data_p->call_info_feat_data.ui_state = CC_UI_STATE_RINGOUT;
                } else if (!cpr_strncasecmp(parm_p, SIP_CI_UI_STATE_CONNECTED,
                                         sizeof(SIP_CI_UI_STATE_CONNECTED) - 1)) {
                    feature_data_p->call_info_feat_data.ui_state = CC_UI_STATE_CONNECTED;
                } else if (!cpr_strncasecmp(parm_p, SIP_CI_UI_STATE_BUSY,
                                         sizeof(SIP_CI_UI_STATE_BUSY) - 1)) {
                    feature_data_p->call_info_feat_data.ui_state = CC_UI_STATE_BUSY;
                } else {
                    CCSIP_DEBUG_ERROR(SIP_F_PREFIX  "Unknown call state"
                                      " value %s\n", fname, parm_p);
                    /* Unknown value, ignore the call state */
                    feature_data_p->call_info_feat_data.feature_flag &=
                         ~(CC_UI_STATE);
                    feature_data_p->call_info_feat_data.ui_state =
                         CC_UI_STATE_NONE;
                }
            } else {
                break;
            }
        } else if (!cpr_strncasecmp(parm_p, SIP_CI_CALL_INSTANCE,
                                    sizeof(SIP_CI_CALL_INSTANCE) - 1)) {
            parm_p = parm_p + sizeof(SIP_CI_CALL_INSTANCE) - 1;
            SKIP_LWS(parm_p);

            if (*parm_p) {
                int idx=0;
                char tempbuf[4];

                feature_data_p->call_info_feat_data.feature_flag |= CC_CALL_INSTANCE;
                /* Initialized the call instance id, just in case */
                feature_data_p->call_info_feat_data.caller_id.call_instance_id
                    = 0;
                /* Parse instance id from line */
                temp_p = parm_p;
                while (isdigit((int) *parm_p)&&idx<3) {
					tempbuf[idx++] = *parm_p++;
                }
                tempbuf[idx] = 0;
                if (idx == 0) {
                    /* Did not find any digit after "call_instance=" */
                    CCSIP_DEBUG_ERROR(SIP_F_PREFIX  "no digits found for"
                                      " call_instance parameter.\n", fname);
                    feature_data_p->call_info_feat_data.feature_flag &=
                             ~(CC_CALL_INSTANCE);
                    break;
                } else {
                    errno = 0;
                    strtoul_result = strtoul(tempbuf, &strtoul_end, 10);

                    if (errno || tempbuf == strtoul_end || strtoul_result > USHRT_MAX) {
                      CCSIP_DEBUG_ERROR(SIP_F_PREFIX  "parse error for call_instance_id: %s",
                                        __FUNCTION__, tempbuf);
                      strtoul_result = 0;
                    }

                    feature_data_p->call_info_feat_data.caller_id.call_instance_id =
                        (uint16_t) strtoul_result;
                }
            } else {
                break;
            }
        } else if (!cpr_strncasecmp(parm_p, SIP_CI_PRIORITY,
                                    sizeof(SIP_CI_PRIORITY) - 1)) {
            parm_p = parm_p + sizeof(SIP_CI_PRIORITY) - 1;
            SKIP_LWS(parm_p);

            if (*parm_p) {
                temp_p = parm_p;
                if ((!cpr_strncasecmp(parm_p, SIP_CI_PRIORITY_URGENT,
                                      sizeof(SIP_CI_PRIORITY_URGENT) - 1)) ||
                    (!cpr_strncasecmp(parm_p, SIP_CI_PRIORITY_EMERGENCY,
                                      sizeof(SIP_CI_PRIORITY_EMERGENCY) - 1))) {
                    feature_data_p->call_info_feat_data.priority = CC_CALL_PRIORITY_URGENT;
                } // otherwise, it will be defaulted to normal priority
                else {
                    errno = 0;
                    strtoul_result = strtoul(temp_p, &strtoul_end, 10);

                    if (errno || temp_p == strtoul_end || strtoul_result > (MAX_CALLS - 1)) {
                        /*
                         * Call instance ID should not exceed max instances
                         * or calls.
                         */
                        CCSIP_DEBUG_ERROR(SIP_F_PREFIX  "invalid call_instance"
                                          " value %u\n", fname, (unsigned) strtoul_result);
                        feature_data_p->call_info_feat_data.feature_flag &=
                                 ~(CC_CALL_INSTANCE);
                    } else {
                        instance_id = (uint16_t) strtoul_result;
                        feature_data_p->call_info_feat_data.caller_id.call_instance_id = instance_id;
                    }
                }
            }
        } else if (!cpr_strncasecmp(parm_p, SIP_CI_GCID,
                                    sizeof(SIP_CI_GCID) - 1)) {
            parm_p = parm_p + sizeof(SIP_CI_GCID) - 1;
            SKIP_LWS(parm_p);
            memset(feature_data_p->call_info_feat_data.global_call_id, 0, CC_GCID_LEN);
            if (*parm_p) {
              temp_p = strchr(parm_p, SEMI_COLON);
              if (temp_p) {
                unsigned int length = ((temp_p - parm_p)<CC_GCID_LEN) ?
                                          (temp_p - parm_p):(CC_GCID_LEN);
                sstrncpy(feature_data_p->call_info_feat_data.global_call_id, parm_p, length);
              } else {
                // No Semicolon found this could be the last parameter
                sstrncpy(feature_data_p->call_info_feat_data.global_call_id, parm_p, CC_GCID_LEN);
              }
              feature_data_p->call_info_feat_data.global_call_id[CC_GCID_LEN-1] = 0;
            }
        } else if (!cpr_strncasecmp(parm_p, SIP_CI_DUSTINGCALL,
                                    sizeof(SIP_CI_DUSTINGCALL) - 1)) {
            parm_p = parm_p + sizeof(SIP_CI_DUSTINGCALL) - 1;
            SKIP_LWS(parm_p);
            feature_data_p->call_info_feat_data.dusting = TRUE;
        }

        parm_p = strchr(parm_p, SEMI_COLON);
    }
}
Beispiel #5
0
/* Function:    sdp_crypto_debug
 * Description: Check the passed buffer for sensitive data that should
 *		not be output (such as SRTP Master Key/Salt) and output
 *		the buffer as debug. Sensitive data will be replaced
 *		with the '*' character(s). This function may be used
 *		to display very large buffers so this function ensures
 *		that buginf is not overloaded.
 * Parameters:  buffer		pointer to the message buffer to filter.
 *              length_bytes	size of message buffer in bytes.
 * Returns:     Nothing.
 */
void sdp_crypto_debug (char *buffer, ulong length_bytes)
{
    char *current, *start;
    char *last = buffer + length_bytes;
    int result;

    /*
     * For SRTP Master Key/Salt has the form:
     * X-crypto:<crypto_suite_name> inline:<master_key_salt>||
     * Where <master_key_salt> is the data to elide (filter).
     */
    for (start=current=buffer;
         current<=last-MIN_CRYPTO_STRING_SIZE_BYTES;
         current++) {
        if ((*current == 'x') || (*current == 'X')) {
            result = cpr_strncasecmp(current, crypto_string, crypto_strlen);
            if (!result) {
                current += crypto_strlen;
                if (current > last) break;

                /* Skip over crypto suite name */
                FIND_WHITESPACE(current, last);

                /* Skip over whitespace */
                SKIP_WHITESPACE(current, last);

                /* identify inline keyword */
                result = cpr_strncasecmp(current, inline_string, inline_strlen);
                if (!result) {
                    int star_count = 0;

                    current += inline_strlen;
                    if (current > last) break;

                    sdp_dump_buffer(start, current - start);

                    /* Hide sensitive key/salt data */
                    while (current<=last) {
                        if (*current == '|' || *current == '\n') {
                            /* Done, print the stars */
                            while (star_count > star_strlen) {
                                /*
                                 * This code is only for the case where
                                 * too much base64 data was supplied
                                 */
                                sdp_dump_buffer((char*)star_string, star_strlen);
                                star_count -= star_strlen;
                            }
                            sdp_dump_buffer((char*)star_string, star_count);
                            break;
                        } else {
                            star_count++;
                            current++;
                        }
                    }
                    /* Update start pointer */
                    start=current;
                }
            }
        }
    }

    if (last > start) {
        /* Display remainder of buffer */
        sdp_dump_buffer(start, last - start);
    }
}