Ejemplo n.º 1
0
/* Get called domain */
static str
getToDomain(char** type, struct sip_msg* msg)
{
    static char buf[16] = "unknown"; // buf is here for a reason. don't
    static str notfound = {buf, 7};  // use the constant string directly!
    static struct sip_uri puri;
    str uri, did;

    if (get_to_did(&did, msg) == 0) {
	*type = "local";
	return did;
    }

    *type = "remote";

    uri = get_to(msg)->uri;

    if (parse_uri(uri.s, uri.len, &puri) < 0) {
        LOG(L_ERR, "error: mediaproxy/getToDomain(): error parsing `To' URI\n");
        return notfound;
    } else if (puri.host.len == 0) {
        return notfound;
    }

    return puri.host;

}
Ejemplo n.º 2
0
// This function only works when called for a request although it's more
// reliable than the getToDomain function.
static str
getDestinationDomain(char** type, struct sip_msg* msg)
{
    static char buf[16] = "unknown"; // buf is here for a reason. don't
    static str notfound = {buf, 7};  // use the constant string directly!
    str did;

    if (get_to_did(&did, msg) == 0) {
	*type = "local";
	return did;
    }

    *type = "remote";

    if (parse_sip_msg_uri(msg) < 0) {
        LOG(L_ERR, "error: mediaproxy/getDestinationDomain(): error parsing destination URI\n");
        return notfound;
    } else if (msg->parsed_uri.host.len==0) {
        return notfound;
    }

    return msg->parsed_uri.host;
}
Ejemplo n.º 3
0
int sd_lookup(struct sip_msg* _msg, char* _index, char* _str2)
{
    int i;
    str user_s, uid, did;
    db_res_t* res = NULL;
    db_rec_t* rec;

    /* init */
    i = (int)(long)_index;

    /* Retrieve the owner of the record */
    if (get_from_uid(&uid, _msg) < 0) {
        LOG(L_ERR, "sd_lookup: Unable to get user identity\n");
        return -1;
    }

    /* Retrieve the called domain id */
    if (get_to_did(&did, _msg) < 0) {
        LOG(L_ERR, "sd_lookup: Destination domain ID not known\n");
        return -1;
    }

    tables[i].lookup_num->match[0].v.lstr = uid;
    tables[i].lookup_num->match[1].v.lstr = did;

    /* Get the called username */
    if (parse_sip_msg_uri(_msg) < 0)
    {
        LOG(L_ERR, "sd_lookup: Error while parsing Request-URI\n");
        goto err_badreq;
    }

    tables[i].lookup_num->match[2].v.lstr = _msg->parsed_uri.user;

    DBG("speeddial: Looking up (uid:%.*s,username:%.*s,did:%.*s)\n",
        uid.len, uid.s,
        _msg->parsed_uri.user.len, _msg->parsed_uri.user.s,
        did.len, did.s);

    if (db_exec(&res, tables[i].lookup_num) < 0) {
        ERR("speeddial: Error while executing database command\n");
        goto err_server;
    }

    if (res == NULL) {
        DBG("speeddial: No SIP URI found for speeddial (num:%.*s, uid:%.*s,"
            " did:%.*s)\n",
            _msg->parsed_uri.user.len,
            _msg->parsed_uri.user.s,
            uid.len, uid.s,
            did.len, did.s);
        return -1;
    }

    user_s.s = useruri_buf + 4;
    rec = db_first(res);
    while(rec) {
        if (rec->fld[0].flags & DB_NULL) goto skip;
        strncpy(user_s.s,
                rec->fld[0].v.lstr.s,
                rec->fld[0].v.lstr.len);
        user_s.len = rec->fld[0].v.lstr.len;
        user_s.s[user_s.len] = '\0';
        goto out;

skip:
        rec = db_next(res);
    }

    if (rec == NULL) {
        DBG("speeddial: No usable SIP URI found for (num:%.*s, uid:%.*s,"
            " did:%.*s)\n",
            _msg->parsed_uri.user.len,
            _msg->parsed_uri.user.s,
            uid.len, uid.s,
            did.len, did.s);
        db_res_free(res);
        return -1;
    }

out:
    /* check 'sip:' */
    if(user_s.len<4 || strncmp(user_s.s, "sip:", 4)) {
        memcpy(useruri_buf, "sip:", 4);
        user_s.s -= 4;
        user_s.len += 4;
    }

    db_res_free(res);

    /* set the URI */
    DBG("sd_lookup: URI of sd from R-URI [%s]\n", user_s.s);
    if(rewrite_uri(_msg, &user_s)<0)
    {
        LOG(L_ERR, "sd_lookup: Cannot replace the R-URI\n");
        goto err_server;
    }

    return 1;

err_server:
    if (slb.zreply(_msg, 500, "Server Internal Error") == -1)
    {
        LOG(L_ERR, "sd_lookup: Error while sending reply\n");
    }
    return 0;
err_badreq:
    if (slb.zreply(_msg, 400, "Bad Request") == -1)
    {
        LOG(L_ERR, "sd_lookup: Error while sending reply\n");
    }
    return 0;
}
Ejemplo n.º 4
0
/*
 * Authorize digest credentials
 */
static inline int authenticate(struct sip_msg* msg, str* realm,
			       hdr_types_t hftype)
{
	int res;
	auth_result_t ret;
	struct hdr_field* h;
	auth_body_t* cred;
	str* uri;
	struct sip_uri puri;
	str user, did;
	VALUE_PAIR* received;

	cred = 0;
	ret = -1;
	user.s = 0;
	received = NULL;

	switch(auth_api.pre_auth(msg, realm, hftype, &h, NULL)) {
	default:
		BUG("unexpected reply '%d'.\n", auth_api.pre_auth(msg, realm, hftype,
				&h, NULL));
#ifdef EXTRA_DEBUG
		abort();
#endif
	case ERROR:
	case BAD_CREDENTIALS:
	    ret = -3;
	    goto end;

	case NOT_AUTHENTICATED:
	    ret = -1;
	    goto end;

	case DO_AUTHENTICATION:
	    break;

	case AUTHENTICATED:
	    ret = 1;
	    goto end;
	}

	cred = (auth_body_t*)h->parsed;

	if (use_did) {
	    if (msg->REQ_METHOD == METHOD_REGISTER) {
			ret = get_to_did(&did, msg);
	    } else {
			ret = get_from_did(&did, msg);
	    }
	    if (ret == 0) {
			did.s = DEFAULT_DID;
			did.len = sizeof(DEFAULT_DID) - 1;
	    }
	} else {
	    did.len = 0;
	    did.s = 0;
	}

	if (get_uri(msg, &uri) < 0) {
		LOG(L_ERR, "authorize(): From/To URI not found\n");
		ret = -1;
		goto end;
	}
	
	if (parse_uri(uri->s, uri->len, &puri) < 0) {
		LOG(L_ERR, "authorize(): Error while parsing From/To URI\n");
		ret = -1;
		goto end;
	}

	user.s = (char *)pkg_malloc(puri.user.len);
	if (user.s == NULL) {
		LOG(L_ERR, "authorize: No memory left\n");
		ret = -1;
		goto end;
	}
	un_escape(&(puri.user), &user);

	res = radius_authorize_sterman(&received, msg, &cred->digest, &msg->first_line.u.request.method, &user);
	if (res == 1) {
	    switch(auth_api.post_auth(msg, h)) {
	    case ERROR:             
	    case BAD_CREDENTIALS:
		ret = -2;
		break;

	    case NOT_AUTHENTICATED:
		ret = -1;
		break;

	    case AUTHENTICATED:
		if (generate_avps(received) < 0) {
		    ret = -1;
		    break;
		}
		ret = 1;
		break;

	    default:
		ret = -1;
		break;
	    }
	} else {
	    ret = -1;
	}

 end:
	if (received) rc_avpair_free(received);
	if (user.s) pkg_free(user.s);
	if (ret < 0) {
	    if (auth_api.build_challenge(msg, (cred ? cred->stale : 0), realm, NULL, NULL, hftype) < 0) {
		ERR("Error while creating challenge\n");
		ret = -2;
	    }
	}
	return ret;
}
Ejemplo n.º 5
0
/*
 * Authenticate digest credentials
 * Returns:
 *      -3 -- Bad Request
 *      -2 -- Error while checking credentials (such as malformed message or database problem)
 *      -1 -- Authentication failed
 *       1 -- Authentication successful
 */
static inline int authenticate(struct sip_msg* msg, str* realm, authdb_table_info_t *table, hdr_types_t hftype)
{
	char ha1[256];
	int res, ret;
	db_rec_t *row;
	struct hdr_field* h;
	auth_body_t* cred;
	db_res_t* result;
	str did;
    
	cred = 0;
	result = 0;
	ret = -1;
    
	switch(auth_api.pre_auth(msg, realm, hftype, &h, NULL)) {
	case ERROR:
	case BAD_CREDENTIALS:
		ret = -3;
		goto end;
	case CREATE_CHALLENGE:
		ERR("auth_db:authenticate: CREATE_CHALLENGE is not a valid state\n");
		ret = -2;
		goto end;
	case DO_RESYNCHRONIZATION:
		ERR("auth_db:authenticate: DO_RESYNCHRONIZATION is not a valid state\n");
		ret = -2;
		goto end;
		
	case NOT_AUTHENTICATED: 
		ret = -1;
		goto end;
		
	case DO_AUTHENTICATION: 
		break;
		
	case AUTHENTICATED:
		ret = 1; 
		goto end;
	}
    
	cred = (auth_body_t*)h->parsed;
	
	if (use_did) {
		if (msg->REQ_METHOD == METHOD_REGISTER) {
			ret = get_to_did(&did, msg);
		} else {
			ret = get_from_did(&did, msg);
		}
		if (ret == 0) {
			did.s = DEFAULT_DID;
			did.len = sizeof(DEFAULT_DID) - 1;
		}
	} else {
		did.len = 0;
		did.s = 0;
	}	
    

	if (check_all) {
		res = check_all_ha1(msg, h, &(cred->digest), &msg->first_line.u.request.method, &did, realm, table, &result);
		if (res < 0) {
			ret = -2;
			goto end;
		}
		else if (res > 0) {
			ret = -1;
			goto end;
		}
		else {
			ret = 1;
			goto end;
		}
    	} else {
		res = get_ha1(&cred->digest.username, &did, realm, table, ha1, &result, &row);
		if (res < 0) {
			ret = -2;
			goto end;
		}
		if (res > 0) {
			/* Username not found in the database */
			ret = -1;
			goto end;
        	}
    	}
    
	/* Recalculate response, it must be same to authorize successfully */
	if (!check_response(&(cred->digest), &msg->first_line.u.request.method, ha1)) {
		switch(auth_api.post_auth(msg, h)) {
		case ERROR:
		case BAD_CREDENTIALS:
			ret = -2; 
			break;
			
		case NOT_AUTHENTICATED: 
			ret = -1; 
			break;
			
		case AUTHENTICATED:
			generate_avps(result, row);
			ret = 1;
			break;
			
		default:
			ret = -1;
			break;
		}
	} else {
		ret = -1;
	}

 end:
	if (result) db_res_free(result);
	if (ret < 0) {
		if (auth_api.build_challenge(msg, (cred ? cred->stale : 0), realm, NULL, NULL, hftype) < 0) {
			ERR("Error while creating challenge\n");
			ret = -2;
		}
	}
	return ret;
}