コード例 #1
0
ファイル: tls-restart.c プロジェクト: ktcunreal/radcli
int process(void *rh, VALUE_PAIR * send, int acct, int nas_port)
{
    VALUE_PAIR *received;
    char msg[PW_MAX_MSG_SIZE];
    char buf[BUF_LEN];
    int i, fd;

    fd = rc_tls_fd(rh);
    if (fd >= 0) {
        dup(fd);
        close(fd);
    }

    received = NULL;
    if (acct == 0) {
        i = rc_auth(rh, nas_port, send, &received, msg);
        if (i != OK_RC) {
            fprintf(stderr, "tls-restart: error sending 1 (ok)\n");
        }

        i = rc_auth(rh, nas_port, send, &received, msg);
        if (i != OK_RC) {
            fprintf(stderr, "tls-restart: error sending 2\n");
            exit(2);
        }
        if (received != NULL) {
            printf("%s", rc_avpair_log(rh, received, buf, BUF_LEN));
            rc_avpair_free(received);
        }
    } else {
        i = rc_acct(rh, nas_port, send);
    }

    return (i == OK_RC) ? 0 : 1;
}
コード例 #2
0
ファイル: checks.c プロジェクト: Drooids/openser-xmlrpc
/*
 * Check from Radius if request URI belongs to a local user.
 * User-Name is user@host of request Uri and Service-Type is Call-Check.
 */
int radius_does_uri_exist(struct sip_msg* _m, char* _s1, char* _s2)
{
	static char msg[4096];
	VALUE_PAIR *send, *received;
	UINT4 service;
	char* at, *uri;

	send = received = 0;

	if (parse_sip_msg_uri(_m) < 0) {
		LM_ERR("parsing URI failed\n");
		return -1;
	}
	
	uri = (char*)pkg_malloc(_m->parsed_uri.user.len + _m->parsed_uri.host.len + 2);
	if (!uri) {
		LM_ERR("no more pkg memory\n");
		return -2;
	}

	at = uri;
	memcpy(at, _m->parsed_uri.user.s, _m->parsed_uri.user.len);
	at += _m->parsed_uri.user.len;
	*at = '@';
	at++;
	memcpy(at , _m->parsed_uri.host.s, _m->parsed_uri.host.len);
	at += _m->parsed_uri.host.len;
	*at = '\0';

	if (!rc_avpair_add(rh, &send, attrs[A_USER_NAME].v, uri, -1, 0)) {
		LM_ERR("adding User-Name failed\n");
		rc_avpair_free(send);
		pkg_free(uri);
	 	return -3;
	}

	service = vals[V_CALL_CHECK].v;
	if (!rc_avpair_add(rh, &send, attrs[A_SERVICE_TYPE].v, &service, -1, 0)) {
		LM_ERR("adding service type failed\n");
		rc_avpair_free(send);
		pkg_free(uri);
	 	return -4;  	
	}
	
	if (rc_auth(rh, 0, send, &received, msg) == OK_RC) {
		LM_DBG("success\n");
		rc_avpair_free(send);
		generate_avps(received);
		rc_avpair_free(received);
		pkg_free(uri);
		return 1;
	} else {
		LM_DBG("failure\n");
		rc_avpair_free(send);
		rc_avpair_free(received);
		pkg_free(uri);
		return -5;
	}
}
コード例 #3
0
ファイル: avp_radius.c プロジェクト: asyn/openvims
static int load_user_attrs(struct sip_msg* msg, unsigned long flags, fparam_t* fp)
{
    static char rad_msg[4096];
    str uid;
    UINT4 service;
    VALUE_PAIR* send, *received;

    send = NULL;
    received = NULL;

    if (get_str_fparam(&uid, msg, (fparam_t*)fp) < 0) {
	ERR("Unable to get UID\n");
	return -1;
    }

    service = vals[V_GET_USER_ATTRS].v;

    if (!rc_avpair_add(rh, &send, ATTRID(attrs[A_USER_NAME].v), 
		       uid.s, uid.len,
		       VENDOR(attrs[A_USER_NAME].v))) {
	ERR("Error while adding A_USER_NAME\n");
	goto error;
    }
    
    if (!rc_avpair_add(rh, &send, ATTRID(attrs[A_SER_SERVICE_TYPE].v), 
		       &vals[V_GET_USER_ATTRS].v, -1, 
		       VENDOR(attrs[A_SER_SERVICE_TYPE].v))) {
	ERR("Error adding A_SERVICE_TYPE\n");
	goto error;
    }


    if (rc_auth(rh, 0, send, &received, rad_msg) != OK_RC) {
	DBG("load_user_attrs: Failure\n");
	goto error;
    }

    DBG("load_user_attrs: Success\n");
    rc_avpair_free(send);

    if (generate_avps(flags, received) < 0) {
	rc_avpair_free(received);
	goto error;
    }

    rc_avpair_free(received);
    return 1;

 error:
    if (send) rc_avpair_free(send);
    if (received) rc_avpair_free(send);
    return -1;
}
コード例 #4
0
ファイル: radius.c プロジェクト: intersvyaz/zerod
/**
 * Perform authenticate request.
 * @param[in] radh Radius handle.
 * @param[out] reply_attr Reply attributes.
 * @param[in,out] reply_msg Reply message.
 * @return One of ZRAD_* codes.
 */
static zrad_status_t zrad_auth_request(rc_handle *radh, const zrad_auth_req_t *req,
                                       VALUE_PAIR **reply_attrs, char *reply_msg)
{
    zrad_status_t ret = ZRAD_OTHER;
    VALUE_PAIR *request_attrs = NULL;

    int success = rc_avpair_add(radh, &request_attrs, PW_USER_NAME, req->username, -1, 0)
                  && rc_avpair_add(radh, &request_attrs, PW_USER_PASSWORD, req->password, -1, 0)
                  && rc_avpair_add(radh, &request_attrs, PW_NAS_IDENTIFIER, req->nas_id, -1, 0)
                  && rc_avpair_add(radh, &request_attrs, PW_CALLING_STATION_ID, req->calling_station_id, -1, 0);

    if (likely(success)) {
        ret = (zrad_status_t) rc_auth(radh, 0, request_attrs, reply_attrs, reply_msg);
    }

    if (likely(request_attrs)) {
        rc_avpair_free(request_attrs);
    }

    return ret;
}
コード例 #5
0
ファイル: functions.c プロジェクト: halan/kamailio
/*
 * Check from Radius if URI, whose user and host parts are given as
 * arguments, exists.  If so, loads AVPs based on reply items returned
 * from Radius.  If use_sip_uri_host module parameter has non-zero value,
 * user is send in SA_USER_NAME attribute and host in SA_SIP_URI_HOST
 * attribute.  If is has zero value, user@host is send in SA_USER_NAME
 * attribute.
 */
int radius_does_uri_user_host_exist(struct sip_msg* _m, str user, str host)
{
    char* at, *user_host;
    VALUE_PAIR *send, *received;
    uint32_t service;
    static char msg[4096];
    int extra_cnt, offset, i, res;

    send = received = 0;
    user_host = 0;

    if (!use_sip_uri_host) {

	/* Send user@host in SA_USER_NAME attr */
	user_host = (char*)pkg_malloc(user.len + host.len + 2);
	if (!user_host) {
	    LM_ERR("no more pkg memory\n");
	    return -1;
	}
	at = user_host;
	memcpy(at, user.s, user.len);
	at += user.len;
	*at = '@';
	at++;
	memcpy(at , host.s, host.len);
	at += host.len;
	*at = '\0';
	if (!rc_avpair_add(rh, &send, uri_attrs[SA_USER_NAME].v, user_host,
			   -1, 0)) {
	    LM_ERR("in adding SA_USER_NAME\n");
	    pkg_free(user_host);
	    return -1;
	}

    } else {

	/* Send user in SA_USER_NAME attribute and host in SA_SIP_URI_HOST
          attribute */
	if (!rc_avpair_add(rh, &send, uri_attrs[SA_USER_NAME].v,
			   user.s, user.len, 0)) {
	    LM_ERR("adding User-Name failed\n");
	    return -1;
	}
	if (!rc_avpair_add(rh, &send, uri_attrs[SA_SIP_URI_HOST].v,
			   host.s, host.len, 0)) {
	    LM_ERR("adding SIP-URI-Host failed\n");
	    goto error;
	}
    }

    service = uri_vals[UV_CALL_CHECK].v;
    if (!rc_avpair_add(rh, &send, uri_attrs[SA_SERVICE_TYPE].v,
		       &service, -1, 0)) {
	LM_ERR("in adding SA_SERVICE_TYPE <%u>\n", service);
	goto error;
    }

    /* Add extra attributes */
    extra_cnt = extra2strar(uri_extra, _m, val_arr);
    if (extra_cnt == -1) {
	LM_ERR("in getting values of group extra attributes\n");
	goto error;
    }
    offset = SA_STATIC_MAX;
    for (i = 0; i < extra_cnt; i++) {
	if (val_arr[i].len == -1) {
	    /* Add integer attribute */
	    ADD_EXTRA_AVPAIR(uri_attrs, offset+i,
			     &(val_arr[i].s), val_arr[i].len );
	} else {
	    /* Add string attribute */
	    ADD_EXTRA_AVPAIR(uri_attrs, offset+i,
			     val_arr[i].s, val_arr[i].len );
	}
    }

    if ((res = rc_auth(rh, 0, send, &received, msg)) == OK_RC) {
	LM_DBG("success\n");
	if (user_host) pkg_free(user_host);
	rc_avpair_free(send);
	generate_avps(uri_attrs, received);
	rc_avpair_free(received);
	return 1;
    } else {
	if (user_host) pkg_free(user_host);
	rc_avpair_free(send);
	rc_avpair_free(received);
#ifdef REJECT_RC
	if (res == REJECT_RC) {
	    LM_DBG("rejected\n");
	    return -1;
	} else {
	    LM_ERR("failure\n");
	    return -2;
	}
#else
	LM_DBG("failure\n");
	return -1;
#endif
    }

 error:
    rc_avpair_free(send);
    if (user_host) pkg_free(user_host);
    return -1;
}
コード例 #6
0
ファイル: functions.c プロジェクト: halan/kamailio
/*
 * Loads from Radius callee's AVPs based on pvar argument.
 * Returns 1 if Radius request succeeded and -1 otherwise.
 */
int radius_load_callee_avps(struct sip_msg* _m, char* _callee, char* _s2)
{
    str user;
    VALUE_PAIR *send, *received;
    uint32_t service;
    static char msg[4096];
    int extra_cnt, offset, i, res;

    send = received = 0;

    if ((_callee == NULL) ||
	(fixup_get_svalue(_m, (gparam_p)_callee, &user) != 0)) {
	LM_ERR("invalid callee parameter");
	return -1;
    }

    if (!rc_avpair_add(rh, &send, callee_attrs[SA_USER_NAME].v,
		       user.s, user.len, 0)) {
	LM_ERR("in adding SA_USER_NAME\n");
	return -1;
    }

    service = callee_vals[EV_SIP_CALLEE_AVPS].v;
    if (!rc_avpair_add(rh, &send, callee_attrs[SA_SERVICE_TYPE].v,
		       &service, -1, 0)) {
	LM_ERR("in adding SA_SERVICE_TYPE <%u>\n", service);
	goto error;
    }

    /* Add extra attributes */
    extra_cnt = extra2strar(callee_extra, _m, val_arr);
    if (extra_cnt == -1) {
	LM_ERR("in getting values of callee extra attributes\n");
	goto error;
    }
    offset = SA_STATIC_MAX;
    for (i = 0; i < extra_cnt; i++) {
	if (val_arr[i].len == -1) {
	    /* Add integer attribute */
	    ADD_EXTRA_AVPAIR(callee_attrs, offset+i,
			     &(val_arr[i].s), val_arr[i].len );
	} else {
	    /* Add string attribute */
	    ADD_EXTRA_AVPAIR(callee_attrs, offset+i,
			     val_arr[i].s, val_arr[i].len );
	}
    }

    if ((res = rc_auth(rh, 0, send, &received, msg)) == OK_RC) {
	LM_DBG("success\n");
	rc_avpair_free(send);
	generate_avps(callee_attrs, received);
	rc_avpair_free(received);
	return 1;
    } else {
	rc_avpair_free(send);
	rc_avpair_free(received);
#ifdef REJECT_RC
	if (res == REJECT_RC) {
	    LM_DBG("rejected\n");
	    return -1;
	} else {
	    LM_ERR("failure\n");
	    return -2;
	}
#else
	LM_DBG("failure\n");
	return -1;
#endif
    }

 error:
    rc_avpair_free(send);
    return -1;
}
コード例 #7
0
ファイル: functions.c プロジェクト: halan/kamailio
/*
 * Check from Radius if a user belongs to a group. User-Name is given in
 * first string argment that may contain pseudo variables.  SIP-Group is
 * given in second string variable that may not contain pseudo variables.
 * Service-Type is Group-Check.
 */
int radius_is_user_in(struct sip_msg* _m, char* _user, char* _group)
{
    str user, *group;
    VALUE_PAIR *send, *received;
    uint32_t service;
    static char msg[4096];
    int extra_cnt, offset, i, res;

    send = received = 0;

    if ((_user == NULL) ||
	(fixup_get_svalue(_m, (gparam_p)_user, &user) != 0)) {
	LM_ERR("invalid user parameter");
	return -1;
    }

    if (!rc_avpair_add(rh, &send, group_attrs[SA_USER_NAME].v,
		       user.s, user.len, 0)) {
	LM_ERR("in adding SA_USER_NAME\n");
	return -1;
    }

    group = (str*)_group;
    if ((group == NULL) || (group->len == 0)) {
	LM_ERR("invalid group parameter");
	goto error;
    }
    if (!rc_avpair_add(rh, &send, group_attrs[SA_SIP_GROUP].v,
		       group->s, group->len, 0)) {
	LM_ERR("in adding SA_SIP_GROUP\n");
	goto error;
    }

    service = group_vals[GV_GROUP_CHECK].v;
    if (!rc_avpair_add(rh, &send, group_attrs[SA_SERVICE_TYPE].v,
		       &service, -1, 0)) {
	LM_ERR("in adding SA_SERVICE_TYPE <%u>\n", service);
	goto error;
    }

    /* Add extra attributes */
    extra_cnt = extra2strar(group_extra, _m, val_arr);
    if (extra_cnt == -1) {
	LM_ERR("in getting values of group extra attributes\n");
	goto error;
    }
    offset = SA_STATIC_MAX;
    for (i = 0; i < extra_cnt; i++) {
	if (val_arr[i].len == -1) {
	    /* Add integer attribute */
	    ADD_EXTRA_AVPAIR(group_attrs, offset+i,
			     &(val_arr[i].s), val_arr[i].len );
	} else {
	    /* Add string attribute */
	    ADD_EXTRA_AVPAIR(group_attrs, offset+i,
			     val_arr[i].s, val_arr[i].len );
	}
    }

    if ((res = rc_auth(rh, 0, send, &received, msg)) == OK_RC) {
	LM_DBG("success\n");
	rc_avpair_free(send);
	generate_avps(group_attrs, received);
	rc_avpair_free(received);
	return 1;
    } else {
	rc_avpair_free(send);
	rc_avpair_free(received);
#ifdef REJECT_RC
	if (res == REJECT_RC) {
	    LM_DBG("rejected\n");
	    return -1;
	} else {
	    LM_ERR("failure\n");
	    return -2;
	}
#else
	LM_DBG("failure\n");
	return -1;
#endif
    }

 error:
    rc_avpair_free(send);
    return -1;
}
コード例 #8
0
/*!
*  Search if the mobile node id is already associated with a prefix in the hnp map
* \param mnid Mobile node ID
* \return a valid prefix if the mobile node id is already associated with a prefix in the hnp map
*/
struct in6_addr mnid_hnp_map(struct in6_addr mnid, int *aaa_result)
{
  int l_flag = 0;
#if !defined (USE_RADIUS) || defined(CACHE_RADIUS)
  int j = 0;
  dbg("Entering the address match . . \n");
  dbg("Searching for MNID  %x:%x:%x:%x:%x:%x:%x:%x  \n", NIP6ADDR(&mnid));

  while (j < g_mn_count) {
    dbg("Comparing with MNID  %x:%x:%x:%x:%x:%x:%x:%x  \n", NIP6ADDR(&g_mn_hn_map[j].mn_iid));

    if (IN6_ARE_ADDR_EQUAL(&g_mn_hn_map[j].mn_iid, &mnid)) {
      l_flag = 1;
      dbg("%x:%x:%x:%x:%x:%x:%x:%x found the prefix \n", NIP6ADDR(&g_mn_hn_map[j].mn_prefix));
      *aaa_result = 10;
      return (g_mn_hn_map[j].mn_prefix);
    }

    j++;
  }

#ifdef CACHE_RADIUS
  dbg("MNID not in cache  %x:%x:%x:%x:%x:%x:%x:%x  \n", NIP6ADDR(&mnid));
#endif
#endif

#if defined (USE_RADIUS)

  VALUE_PAIR *send, *received;
  VALUE_PAIR *vp;
  struct in6_addr prefix;
  uint32_t service;

  *aaa_result = 0;
  send = NULL;

  sprintf(g_username, "%04x%04x%04x%04x", ntohs(mnid.s6_addr16[4]), ntohs(mnid.s6_addr16[5]), ntohs(mnid.s6_addr16[6]), ntohs(mnid.s6_addr16[7]));
  g_username[16] = 0;
  memset(g_passwd, '\0', AUTH_PASS_LEN + 1);
  strncpy(g_passwd, conf.RadiusPassword, strlen(conf.RadiusPassword));
  g_passwd[strlen(conf.RadiusPassword)] = '\0';
  // Fill in User-Name

  strncpy(g_username_realm, g_username, sizeof(g_username_realm));

  // Append default realm
  if ((strchr(g_username_realm, '@') == NULL) && g_default_realm && (*g_default_realm != '\0')) {
    strncat(g_username_realm, "@", sizeof(g_username_realm) - strlen(g_username_realm) - 1);
    strncat(g_username_realm, g_default_realm, sizeof(g_username_realm) - strlen(g_username_realm) - 1);
  }

  dbg("RADIUS USER NAME %s\n", g_username_realm);
  dbg("RADIUS PASSWORD  %s\n", g_passwd);

  if (rc_avpair_add(g_rh, &send, PW_USER_NAME, g_username_realm, -1, 0) == NULL) {
    fprintf(stderr, "[RADIUS] ERROR rc_avpair_add PW_USER_NAME\n");
  } else {
    //
    // Fill in User-Password

    if (rc_avpair_add(g_rh, &send, PW_USER_PASSWORD, g_passwd, -1, 0) == NULL) {
      fprintf(stderr, "[RADIUS] ERROR rc_avpair_add PW_USER_PASSWORD\n");
    } else {

      // Fill in Service-Type

      service = PW_AUTHENTICATE_ONLY;

      if (rc_avpair_add(g_rh, &send, PW_SERVICE_TYPE, &service, -1, 0) == NULL) {
        fprintf(stderr, "[RADIUS] ERROR rc_avpair_add PW_SERVICE_TYPE\n");
      } else {
        // result = RESULT always < 0 !!!
        rc_auth(g_rh, 0, send, &received, msg);
        {
          *aaa_result = 0;

          if (received != NULL) {
            if ((vp = rc_avpair_get(received, PW_FRAMED_IPV6_PREFIX, 0)) != NULL) {
              *aaa_result += 1;
              int netmask = vp->strvalue[1];
              int num_bytes = netmask / 8;
              int i;

              for (i = 0; i < num_bytes; i++) {
                prefix.s6_addr[i] = vp->strvalue[2 + i];
              }

              for (i = num_bytes; i < 16; i++) {
                prefix.s6_addr[i] = 0;
              }
            }

            if ((vp = rc_avpair_get(received, PW_FRAMED_INTERFACE_ID, 0)) != NULL) {
              *aaa_result += 1;
              int i;

              for (i = 0; i < 8; i++) {
                prefix.s6_addr[8 + i] = prefix.s6_addr[8 + i] | vp->strvalue[i];
              }
            }

            rc_avpair_free(received);
          }

          if (*aaa_result >= 2) {
            l_flag = 1;
            dbg("[RADIUS] Assigned IPv6 @ for MN UID %x:%x:%x:%x:%x:%x:%x:%x <=> %x:%x:%x:%x:%x:%x:%x:%x\n", NIP6ADDR(&mnid), NIP6ADDR(&prefix));
            dbg("[RADIUS] \"%s\" Authentication OK\n", g_username);
            pmip_insert_into_hnp_cache(mnid, prefix);
            return prefix;
          }
        }
      }
    }
  }

#endif
  dbg("mnid not found\n");
  struct in6_addr tmp;
  memset(&tmp, 0, sizeof(struct in6_addr));
  *aaa_result = -1;
  return tmp;
}
コード例 #9
0
ファイル: avp_radius.c プロジェクト: asyn/openvims
static int load_uri_attrs(struct sip_msg* msg, unsigned long flags, fparam_t* fp)
{
    static char rad_msg[4096];
    struct sip_uri puri;
    str uri, did, scheme;
    UINT4 service;
    VALUE_PAIR* send, *received;

    send = NULL;
    received = NULL;

    if (get_str_fparam(&uri, msg, (fparam_t*)fp) != 0) {
	ERR("Unable to get URI\n");
	return -1;
    }

    if (parse_uri(uri.s, uri.len, &puri) < 0) {
	ERR("Error while parsing URI '%.*s'\n", uri.len, uri.s);
	return -1;
    }

    if (puri.host.len) {
	/* domain name is present */
	if (dm_get_did(&did, &puri.host) < 0) {
		DBG("Cannot lookup DID for domain %.*s, using default value\n", puri.host.len, ZSW(puri.host.s));
		did.s = DEFAULT_DID;
		did.len = sizeof(DEFAULT_DID) - 1;
	}
    } else {
	/* domain name is missing -- can be caused by tel: URI */
	DBG("There is no domain name, using default value\n");
	did.s = DEFAULT_DID;
	did.len = sizeof(DEFAULT_DID) - 1;
    }

    uri_type_to_str(puri.type, &scheme);
    service = vals[V_GET_URI_ATTRS].v;

    if (scheme.len) {
	if (!rc_avpair_add(rh, &send, ATTRID(attrs[A_SER_URI_SCHEME].v), 
			   scheme.s, scheme.len,
			   VENDOR(attrs[A_SER_URI_SCHEME].v))) {
	    ERR("Error while adding A_SER_URI_SCHEME\n");
	    goto error;
	}
    }

    if (!rc_avpair_add(rh, &send, ATTRID(attrs[A_USER_NAME].v), 
		       puri.user.s, puri.user.len,
		       VENDOR(attrs[A_USER_NAME].v))) {
	ERR("Error while adding A_USER_NAME\n");
	goto error;
    }

    if (!rc_avpair_add(rh, &send, ATTRID(attrs[A_SER_DID].v), 
		       did.s, did.len,
		       VENDOR(attrs[A_SER_DID].v))) {
	ERR("Error while adding A_SER_DID\n");
	goto error;
    }
    
    if (!rc_avpair_add(rh, &send, ATTRID(attrs[A_SER_SERVICE_TYPE].v), 
		       &vals[V_GET_URI_ATTRS].v, -1,
		       VENDOR(attrs[A_SER_SERVICE_TYPE].v))) {
	ERR("Error adding A_SERVICE_TYPE\n");
	goto error;
    }

    if (rc_auth(rh, 0, send, &received, rad_msg) != OK_RC) {
	DBG("load_uri_attrs: Failure\n");
	goto error;
    }

    DBG("load_uri_attrs: Success\n");
    rc_avpair_free(send);

    if (generate_avps(flags, received) < 0) {
	rc_avpair_free(received);
	goto error;
    }

    rc_avpair_free(received);
    return 1;

 error:
    if (send) rc_avpair_free(send);
    if (received) rc_avpair_free(send);
    return -1;
}
コード例 #10
0
static int load_avp_user(struct sip_msg* msg, str* prefix, load_avp_param_t type)
{
	static char rad_msg[4096];
	str user_domain, buffer;
	str* user, *domain, *uri;
	struct hdr_field* h;
	dig_cred_t* cred = 0;
	int_str name, val;
	unsigned short flags;

	VALUE_PAIR* send, *received, *vp;
	UINT4 service;
	struct sip_uri puri;
	
	send = received = 0;
	user_domain.s = 0;

	switch(type) {
	case LOAD_CALLER:
		     /* Use From header field */
		if (parse_from_header(msg) < 0) {
			LOG(L_ERR, "ERROR:avp_radius:load_avp_user: Error while "
				"parsing From header field\n");
			return -1;
		}

		uri = &get_from(msg)->uri;
		if (parse_uri(uri->s, uri->len, &puri) == -1) {
			LOG(L_ERR, "ERROR:avp_radius:load_avp_user: Error while "
				"parsing From URI\n");
			return -1;
		}

		user = &puri.user;
		domain = &puri.host;
		service = vals[V_SIP_CALLER_AVPS].v;
		break;

	case LOAD_CALLEE:
		     /* Use the Request-URI */
		if (parse_sip_msg_uri(msg) < 0) {
			LOG(L_ERR, "ERROR:avp_radius:load_avp_user: Error while "
				"parsing Request-URI\n");
			return -1;
		}

		if (msg->parsed_uri.user.len == 0) {
			LOG(L_ERR, "ERROR:avp_radius:load_avp_user: Request-URI user "
				"is missing\n");
			return -1;
		}
		
		user = &msg->parsed_uri.user; 
		domain = &msg->parsed_uri.host;
		service = vals[V_SIP_CALLEE_AVPS].v;
		break;

	case LOAD_DIGEST:
		     /* Use digest credentials */
		get_authorized_cred(msg->proxy_auth, &h);
		if (!h) {
			LOG(L_ERR, "ERROR:avp_radius:load_avp_user: No authoried "
				"credentials\n");
			return -1;
		}

		cred = &((auth_body_t*)(h->parsed))->digest;
		user = &cred->username.user;
		domain = &cred->realm;
		service = vals[V_SIP_CALLER_AVPS].v;
		break;

	default:
		LOG(L_ERR, "ERROR:avp_radius:avp_load_user: Unknown user type\n");
		return -1;
		
	}

	user_domain.len = user->len + 1 + domain->len;
	user_domain.s = (char*)pkg_malloc(user_domain.len);
	if (!user_domain.s) {
		LOG(L_ERR, "ERROR:avp_radius:avp_load_user: No pkg memory left\n");
		return -1;
	}

	memcpy(user_domain.s, user->s, user->len);
	user_domain.s[user->len] = '@';
	memcpy(user_domain.s + user->len + 1, domain->s, domain->len);

	if (!rc_avpair_add(rh, &send, attrs[A_USER_NAME].v,
			user_domain.s, user_domain.len, 0)) {
		LOG(L_ERR, "ERROR:avp_radius:avp_load_user: Error adding "
			"PW_USER_NAME\n");
		goto error;
	}

	if (!rc_avpair_add(rh, &send, attrs[A_SERVICE_TYPE].v, &service, -1, 0)) {
		LOG(L_ERR, "ERROR:avp_radius:avp_load_user: Error adding "
			"PW_SERVICE_TYPE\n");
		goto error;
	}

	if (rc_auth(rh, 0, send, &received, rad_msg) == OK_RC) {
		DBG("DEBUG:avp_radius:avp_load_user: rc_auth Success\n");
		rc_avpair_free(send);
		pkg_free(user_domain.s);

		vp = received;
		for( ; (vp=rc_avpair_get(vp,attrs[A_SIP_AVP].v,0)) ; vp=vp->next) {
			flags = 0;
			if (extract_avp( vp, &flags, &name, &val)!=0 )
				continue;

			/* append prefix only if AVP has name */
			if (flags&AVP_NAME_STR) {
				buffer.len = prefix->len + name.s->len;
				buffer.s = (char*)pkg_malloc(buffer.len);
				if (!buffer.s) {
					LOG(L_ERR, "ERROR:avp_radius:avp_load_user: "******"No pkg memory left\n");
					return -1;
				}
				memcpy(buffer.s, prefix->s, prefix->len);
				memcpy(buffer.s + prefix->len, name.s->s, name.s->len);
				name.s = &buffer;
			} else {
				buffer.s = 0;
			}

			if (add_avp( flags, name, val) < 0) {
				LOG(L_ERR, "ERROR:avp_radius:avp_load_user: Unable to create "
					"a new AVP\n");
			} else {
				DBG("DEBUG:avp_radius:generate_avps: "
					"AVP '%.*s'/%d='%.*s'/%d has been added\n",
					(flags&AVP_NAME_STR)?name.s->len:4,
					(flags&AVP_NAME_STR)?name.s->s:"null",
					(flags&AVP_NAME_STR)?0:name.n,
					(flags&AVP_VAL_STR)?val.s->len:4,
					(flags&AVP_VAL_STR)?val.s->s:"null",
					(flags&AVP_VAL_STR)?0:val.n );
			}

			if (buffer.s) 
				pkg_free(buffer.s);
		}

		rc_avpair_free(received);
		return 1;
	} else {
		LOG(L_ERR,"ERROR:avp_radius:avp_load_user: rc_auth failed\n");
	}

error:
	if (send) rc_avpair_free(send);
	if (received) rc_avpair_free(received);
	if (user_domain.s) pkg_free(user_domain.s);
	return -1;
}
コード例 #11
0
ファイル: radius.c プロジェクト: WiseMan787/ralink_sdk
LFUNC auth_radius(UINT4 client_port, char *username, char *passwd)
{

	VALUE_PAIR	*send, *received, *vp, *service_vp;
	UINT4		service, ftype, ctype;
	char		msg[4096], *p, username_realm[256];
	char            name[2048], value[2048]; /* more than enough */
	int		result;
	char		*default_realm, *service_str, *ftype_str;
	DICT_VALUE	*dval;

	send = received = NULL;

	/*
	 * Determine and fill in Service-Type
	 */

#ifdef SCP
	/* determine based on the username what kind of service is requested.
	   this allows you to use one password for all accounts, but the
	   Merit radiusd supplies you just with the right information you
	   need for the specified service type	-lf, 03/15/96 */

	switch (*username)
	{
		case 'S':
				service = PW_FRAMED;
				ftype = PW_SLIP;
				ctype = 0;
				username++;
				break;
		case 'C':
				service = PW_FRAMED;
				ftype = PW_SLIP;
				ctype = PW_VAN_JACOBSON_TCP_IP;
				username++;
				break;
		case 'P':
				service = PW_FRAMED;
				ftype = PW_PPP;
				ctype = 0;
				username++;
				break;
		default:
				service = PW_LOGIN;
				ftype = 0;
				ctype = 0;
				break;
	}
#else
	service = PW_LOGIN;
	ftype = 0;
	ctype = 0;
#endif

	if (rc_avpair_add(&send, PW_SERVICE_TYPE, &service, 0, VENDOR_NONE) == NULL)
		return (LFUNC) NULL;

	/* Fill in Framed-Protocol, if neccessary */

	if (ftype != 0)
	{
		if (rc_avpair_add(&send, PW_FRAMED_PROTOCOL, &ftype, 0, VENDOR_NONE) == NULL)
			return (LFUNC) NULL;
	}

	/* Fill in Framed-Compression, if neccessary */

	if (ctype != 0)
	{
		if (rc_avpair_add(&send, PW_FRAMED_COMPRESSION, &ctype, 0, VENDOR_NONE) == NULL)
			return (LFUNC) NULL;
	}

	/*
	 * Fill in User-Name
	 */

	 strncpy(username_realm, username, sizeof(username_realm));

	 /* Append default realm */
	 default_realm = rc_conf_str("default_realm");

	 if ((strchr(username_realm, '@') == NULL) && default_realm &&
	     ((*default_realm) != '\0'))
	 {
		strncat(username_realm, "@", sizeof(username_realm));
		strncat(username_realm, default_realm, sizeof(username_realm));
	 }

	if (rc_avpair_add(&send, PW_USER_NAME, username_realm, 0, VENDOR_NONE) == NULL)
		return (LFUNC) NULL;

	/*
	 * Fill in User-Password
	 */

	if (rc_avpair_add(&send, PW_USER_PASSWORD, passwd, 0, VENDOR_NONE) == NULL)
		return (LFUNC) NULL;

	result = rc_auth(client_port, send, &received, msg, NULL);

	if (result == OK_RC)
	{
		/* Set up a running count of attributes saved. */
		int acount[256], attr;

		memset(acount, 0, sizeof(acount));

		rc_add_env(env, "RADIUS_USER_NAME", username);

		vp = received;

		/* map-- keep track of the attributes so that we know
		   when to add the delimiters. Note that we can only
		   handle attributes < 256, which is the standard anyway. */

		while (vp)
		{
			strcpy(name, "RADIUS_");
			if (rc_avpair_tostr(vp, name+7, sizeof(name)-7, value, sizeof(value)) < 0) {
				rc_avpair_free(send);
				rc_avpair_free(received);
				return (LFUNC) NULL;
			}

			/* Translate "-" => "_" and uppercase*/
			for(p = name; *p; p++) {
				*p = toupper(*p);
				if (*p == '-') *p = '_';
			}

			/* Add to the attribute count and append the var
			   if necessary. */
			if ((attr = vp->attribute) < 256)
			{
				int count;
				if ((count = acount[attr]++) > 0) {
					char buf[10];
					sprintf(buf, "_%d", count);
					strcat(name,buf);
				}
			}

			if (rc_add_env(env, name, value) < 0)
			{
				rc_avpair_free(send);
				rc_avpair_free(received);
				return (LFUNC) NULL;
			}

			vp = vp->next;
		}

		service_str = "(unknown)";
		ftype_str = NULL;

		if ((service_vp = rc_avpair_get(received, PW_SERVICE_TYPE)) != NULL)
				if ((dval = rc_dict_getval(service_vp->lvalue, service_vp->name)) != NULL) {
					service_str = dval->name;
				}

		if (service_vp && (service_vp->lvalue == PW_FRAMED) &&
			((vp = rc_avpair_get(received, PW_FRAMED_PROTOCOL)) != NULL))
				if ((dval = rc_dict_getval(vp->lvalue, vp->name)) != NULL) {
					ftype_str = dval->name;
				}

		rc_log(LOG_NOTICE, "authentication OK, username %s, service %s%s%s",
				username, service_str,(ftype_str)?"/":"", (ftype_str)?ftype_str:"");

		if (msg && (*msg != '\0'))
			printf(SC_SERVER_REPLY, msg);
		else
			printf(SC_RADIUS_OK);

		rc_avpair_free(send);
		rc_avpair_free(received);

		return radius_login;
	}
	else
	{
		rc_log(LOG_NOTICE, "authentication FAILED, type RADIUS, username %s",
			   username_realm);
		if (msg && (*msg != '\0'))
			printf(SC_SERVER_REPLY, msg);
		else
			printf(SC_RADIUS_FAILED);
	}

	rc_avpair_free(send);
	if (received)
		rc_avpair_free(received);

	return (LFUNC) NULL;
}
コード例 #12
0
ファイル: sterman.c プロジェクト: OPSF/uClinux
/*
 * This function creates and submits radius authentication request as per
 * draft-sterman-aaa-sip-00.txt.  In addition, _user parameter is included
 * in the request as value of a SER specific attribute type SIP-URI-User,
 * which can be be used as a check item in the request.  Service type of
 * the request is Authenticate-Only.
 */
int radius_authorize_sterman(struct sip_msg* _msg, dig_cred_t* _cred, str* _method, str* _user, str* _rpid) 
{
	static char msg[4096];
	VALUE_PAIR *send, *received, *vp;
	UINT4 service;
	str method, user, user_name, callid;
	int i;
	
	send = received = 0;

	if (!(_cred && _method && _user && _rpid)) {
		LOG(L_ERR, "radius_authorize_sterman(): Invalid parameter value\n");
		return -1;
	}

	method = *_method;
	user = *_user;

	/*
	 * Add all the user digest parameters according to the qop defined.
	 * Most devices tested only offer support for the simplest digest.
	 */

	if (_cred->username.domain.len) {
		if (!rc_avpair_add(rh, &send, attrs[A_USER_NAME].v, _cred->username.whole.s, _cred->username.whole.len, 0)) {
			LOG(L_ERR, "sterman(): Unable to add User-Name attribute\n");
			rc_avpair_free(send);
			return -2;
		}
	} else {
		user_name.len = _cred->username.user.len + _cred->realm.len + 1;
		user_name.s = pkg_malloc(user_name.len);
		if (!user_name.s) {
			LOG(L_ERR, "radius_authorize_sterman(): No memory left\n");
			return -3;
		}
		memcpy(user_name.s, _cred->username.whole.s, _cred->username.whole.len);
		user_name.s[_cred->username.whole.len] = '@';
		memcpy(user_name.s + _cred->username.whole.len + 1, _cred->realm.s, _cred->realm.len);
		if (!rc_avpair_add(rh, &send, attrs[A_USER_NAME].v, user_name.s, user_name.len, 0)) {
			LOG(L_ERR, "sterman(): Unable to add User-Name attribute\n");
			pkg_free(user_name.s);
			rc_avpair_free(send);
			return -4;
		}
		pkg_free(user_name.s);
	}

	if (!rc_avpair_add(rh, &send, attrs[A_DIGEST_USER_NAME].v, _cred->username.whole.s, _cred->username.whole.len, 0)) {
		LOG(L_ERR, "sterman(): Unable to add Digest-User-Name attribute\n");
		rc_avpair_free(send);
		return -5;
	}

	if (!rc_avpair_add(rh, &send, attrs[A_DIGEST_REALM].v, _cred->realm.s, _cred->realm.len, 0)) {
		LOG(L_ERR, "sterman(): Unable to add Digest-Realm attribute\n");
		rc_avpair_free(send);
		return -6;
	}
	if (!rc_avpair_add(rh, &send, attrs[A_DIGEST_NONCE].v, _cred->nonce.s, _cred->nonce.len, 0)) {
		LOG(L_ERR, "sterman(): Unable to add Digest-Nonce attribute\n");
		rc_avpair_free(send);
		return -7;
	}
	
	if (!rc_avpair_add(rh, &send, attrs[A_DIGEST_URI].v, _cred->uri.s, _cred->uri.len, 0)) {
		LOG(L_ERR, "sterman(): Unable to add Digest-URI attribute\n");
		rc_avpair_free(send);
		return -8;
	}
	if (!rc_avpair_add(rh, &send, attrs[A_DIGEST_METHOD].v, method.s, method.len, 0)) {
		LOG(L_ERR, "sterman(): Unable to add Digest-Method attribute\n");
		rc_avpair_free(send);
		return -9;
	}
	
	/* 
	 * Add the additional authentication fields according to the QOP.
	 */
	if (_cred->qop.qop_parsed == QOP_AUTH) {
		if (!rc_avpair_add(rh, &send, attrs[A_DIGEST_QOP].v, "auth", 4, 0)) {
			LOG(L_ERR, "sterman(): Unable to add Digest-QOP attribute\n");
			rc_avpair_free(send);
			return -10;
		}
		if (!rc_avpair_add(rh, &send, attrs[A_DIGEST_NONCE_COUNT].v, _cred->nc.s, _cred->nc.len, 0)) {
			LOG(L_ERR, "sterman(): Unable to add Digest-CNonce-Count attribute\n");
			rc_avpair_free(send);
			return -11;
		}
		if (!rc_avpair_add(rh, &send, attrs[A_DIGEST_CNONCE].v, _cred->cnonce.s, _cred->cnonce.len, 0)) {
			LOG(L_ERR, "sterman(): Unable to add Digest-CNonce attribute\n");
			rc_avpair_free(send);
			return -12;
		}
	} else if (_cred->qop.qop_parsed == QOP_AUTHINT) {
		if (!rc_avpair_add(rh, &send, attrs[A_DIGEST_QOP].v, "auth-int", 8, 0)) {
			LOG(L_ERR, "sterman(): Unable to add Digest-QOP attribute\n");
			rc_avpair_free(send);
			return -13;
		}
		if (!rc_avpair_add(rh, &send, attrs[A_DIGEST_NONCE_COUNT].v, _cred->nc.s, _cred->nc.len, 0)) {
			LOG(L_ERR, "sterman(): Unable to add Digest-Nonce-Count attribute\n");
			rc_avpair_free(send);
			return -14;
		}
		if (!rc_avpair_add(rh, &send, attrs[A_DIGEST_CNONCE].v, _cred->cnonce.s, _cred->cnonce.len, 0)) {
			LOG(L_ERR, "sterman(): Unable to add Digest-CNonce attribute\n");
			rc_avpair_free(send);
			return -15;
		}
		if (!rc_avpair_add(rh, &send, attrs[A_DIGEST_BODY_DIGEST].v, _cred->opaque.s, _cred->opaque.len, 0)) {
			LOG(L_ERR, "sterman(): Unable to add Digest-Body-Digest attribute\n");
			rc_avpair_free(send);
			return -16;
		}
		
	} else  {
		/* send nothing for qop == "" */
	}

	/* Add the response... What to calculate against... */
	if (!rc_avpair_add(rh, &send, attrs[A_DIGEST_RESPONSE].v, _cred->response.s, _cred->response.len, 0)) {
		LOG(L_ERR, "sterman(): Unable to add Digest-Response attribute\n");
		rc_avpair_free(send);
		return -17;
	}

	/* Indicate the service type, Authenticate only in our case */
	service = vals[V_SIP_SESSION].v;
	if (!rc_avpair_add(rh, &send, attrs[A_SERVICE_TYPE].v, &service, -1, 0)) {
		LOG(L_ERR, "sterman(): Unable to add Service-Type attribute\n");
		rc_avpair_free(send);
	 	return -18;
	}

	/* Add SIP URI as a check item */
	if (!rc_avpair_add(rh, &send, attrs[A_SIP_URI_USER].v, user.s, user.len, 0)) {
		LOG(L_ERR, "sterman(): Unable to add Sip-URI-User attribute\n");
		rc_avpair_free(send);
	 	return -19;  	
	}

	if (attrs[A_CISCO_AVPAIR].n != NULL) {
		/* Add SIP Call-ID as a Cisco VSA, like IOS does */
		if (_msg->callid == NULL || _msg->callid->body.s == NULL) {
			LOG(L_ERR, "sterman(): Call-ID is missed\n");
			rc_avpair_free(send);
			return -20;
		}
		callid.len = _msg->callid->body.len + 8;
		callid.s = alloca(callid.len);
		if (callid.s == NULL) {
			LOG(L_ERR, "sterman(): No memory left\n");
			rc_avpair_free(send);
			return -21;
		}
		memcpy(callid.s, "call-id=", 8);
		memcpy(callid.s + 8, _msg->callid->body.s, _msg->callid->body.len);
		if (rc_avpair_add(rh, &send, attrs[A_CISCO_AVPAIR].v, callid.s,
		    callid.len, VENDOR(attrs[A_CISCO_AVPAIR].v)) == 0) {
			LOG(L_ERR, "sterman(): Unable to add Cisco-AVPair attribute\n");
			rc_avpair_free(send);
			return -22;
 		}
	}

	/* Send request */
	if ((i = rc_auth(rh, SIP_PORT, send, &received, msg)) == OK_RC) {
		DBG("radius_authorize_sterman(): Success\n");
		rc_avpair_free(send);

		     /* Make a copy of rpid if available */
		if ((vp = rc_avpair_get(received, attrs[A_SIP_RPID].v, 0))) {
			if (MAX_RPID_LEN < vp->lvalue) {
				LOG(L_ERR, "radius_authorize_sterman(): rpid buffer too small\n");
				return -23;
			}
			memcpy(_rpid->s, vp->strvalue, vp->lvalue);
			_rpid->len = vp->lvalue;
		}

		rc_avpair_free(received);
		return 1;
	} else {
		DBG("res: %d\n", i);
		DBG("radius_authorize_sterman(): Failure\n");
		rc_avpair_free(send);
		rc_avpair_free(received);
		return -24;
	}
}
コード例 #13
0
/*
 * Check from Radius if a user belongs to a group. User-Name is digest
 * username or digest username@realm, SIP-Group is group, and Service-Type
 * is Group-Check.  SIP-Group is SER specific attribute and Group-Check is
 * SER specific service type value.
 */
int radius_is_user_in(struct sip_msg* _m, char* _hf, char* _group)
{
	str *grp, user_name, user, domain, uri;
	dig_cred_t* cred = 0;
	int hf_type;
	UINT4 service;
	VALUE_PAIR *send, *received;
	static char msg[4096];
	struct hdr_field* h;
	struct sip_uri puri;

	grp = (str*)_group; /* via fixup */
	send = received = 0;

	hf_type = (int)(long)_hf;

	uri.s = 0;
	uri.len = 0;

	switch(hf_type) {
	case 1: /* Request-URI */
		if (get_request_uri(_m, &uri) < 0) {
			LOG(L_ERR, "radius_is_user_in(): Error while extracting Request-URI\n");
			return -1;
		}
		break;

	case 2: /* To */
		if (get_to_uri(_m, &uri) < 0) {
			LOG(L_ERR, "radius_is_user_in(): Error while extracting To\n");
			return -2;
		}
		break;

	case 3: /* From */
		if (get_from_uri(_m, &uri) < 0) {
			LOG(L_ERR, "radius_is_user_in(): Error while extracting From\n");
			return -3;
		}
		break;

	case 4: /* Credentials */
		get_authorized_cred(_m->authorization, &h);
		if (!h) {
			get_authorized_cred(_m->proxy_auth, &h);
			if (!h) {
				LOG(L_ERR, "radius_is_user_in(): No authorized credentials found (error in scripts)\n");
				return -4;
			}
		}
		cred = &((auth_body_t*)(h->parsed))->digest;
		break;
	}

	if (hf_type != 4) {
		if (parse_uri(uri.s, uri.len, &puri) < 0) {
			LOG(L_ERR, "radius_is_user_in(): Error while parsing URI\n");
			return -5;
		}
		user = puri.user;
		domain = puri.host;
	} else {
		user = cred->username.user;
		domain = *GET_REALM(cred);
	}
		

	if (use_domain) {
		user_name.len = user.len + domain.len + 1;
		user_name.s = (char*)pkg_malloc(user_name.len);
		if (!user_name.s) {
			LOG(L_ERR, "radius_is_user_in(): No memory left\n");
			return -6;
		}
		
		memcpy(user_name.s, user.s, user.len);
		user_name.s[user.len] = '@';
		memcpy(user_name.s + user.len + 1, domain.s, domain.len);
	} else {
		user_name = user;
	}

	if (!rc_avpair_add(rh, &send, attrs[A_USER_NAME].v, user_name.s, user_name.len, 0)) {
		LOG(L_ERR, "radius_is_user_in(): Error adding User-Name attribute\n");
		rc_avpair_free(send);
		if (use_domain) pkg_free(user_name.s);
		return -7;
	}

	if (use_domain) pkg_free(user_name.s);

	if (!rc_avpair_add(rh, &send, attrs[A_SIP_GROUP].v, grp->s, grp->len, 0)) {
		LOG(L_ERR, "radius_is_user_in(): Error adding Sip-Group attribute\n");
	 	return -8;  	
	}

	service = vals[V_GROUP_CHECK].v;
	if (!rc_avpair_add(rh, &send, attrs[A_SERVICE_TYPE].v, &service, -1, 0)) {
		LOG(L_ERR, "radius_is_user_in(): Error adding Service-Type attribute\n");
		rc_avpair_free(send);
	 	return -9;  	
	}

	if (rc_auth(rh, 0, send, &received, msg) == OK_RC) {
		DBG("radius_is_user_in(): Success\n");
		rc_avpair_free(send);
		rc_avpair_free(received);
		return 1;
	} else {
		DBG("radius_is_user_in(): Failure\n");
		rc_avpair_free(send);
		rc_avpair_free(received);
		return -11;
	}
}
コード例 #14
0
/*
 * This function creates and submits radius authentication request as per
 * draft-sterman-aaa-sip-00.txt.  In addition, _user parameter is included
 * in the request as value of a SER specific attribute type SIP-URI-User,
 * which can be be used as a check item in the request.  Service type of
 * the request is Authenticate-Only.
 */
int radius_authorize_sterman(dig_cred_t* _cred, str* _method, str* _user, str* _rpid) 
{
	static char msg[4096];
	VALUE_PAIR *send, *received, *vp;
	UINT4 service;
	str method, user, user_name;
	int i;
	
	send = received = 0;

	if (!(_cred && _method && _user && _rpid)) {
		LOG(L_ERR, "radius_authorize_sterman(): Invalid parameter value\n");
		return -1;
	}

	method = *_method;
	user = *_user;

	/*
	 * Add all the user digest parameters according to the qop defined.
	 * Most devices tested only offer support for the simplest digest.
	 */

	if (_cred->username.domain.len) {
		if (!rc_avpair_add(&send, PW_USER_NAME, _cred->username.whole.s, _cred->username.whole.len)) {
			LOG(L_ERR, "sterman(): Unable to add PW_USER_NAME attribute\n");
			rc_avpair_free(send);
			return -2;
		}
	} else {
		user_name.len = _cred->username.user.len + _cred->realm.len + 1;
		user_name.s = pkg_malloc(user_name.len);
		if (!user_name.s) {
			LOG(L_ERR, "radius_authorize_sterman(): No memory left\n");
			return -3;
		}
		memcpy(user_name.s, _cred->username.whole.s, _cred->username.whole.len);
		user_name.s[_cred->username.whole.len] = '@';
		memcpy(user_name.s + _cred->username.whole.len + 1, _cred->realm.s, _cred->realm.len);
		if (!rc_avpair_add(&send, PW_USER_NAME, user_name.s, user_name.len)) {
			LOG(L_ERR, "sterman(): Unable to add PW_USER_NAME attribute\n");
			pkg_free(user_name.s);
			rc_avpair_free(send);
			return -4;
		}
		pkg_free(user_name.s);
	}

	if (!rc_avpair_add(&send, PW_DIGEST_USER_NAME, _cred->username.whole.s, _cred->username.whole.len)) {
		LOG(L_ERR, "sterman(): Unable to add PW_DIGEST_USER_NAME attribute\n");
		rc_avpair_free(send);
		return -5;
	}

	if (!rc_avpair_add(&send, PW_DIGEST_REALM, _cred->realm.s, _cred->realm.len)) {
		LOG(L_ERR, "sterman(): Unable to add PW_DIGEST_REALM attribute\n");
		rc_avpair_free(send);
		return -6;
	}
	if (!rc_avpair_add(&send, PW_DIGEST_NONCE, _cred->nonce.s, _cred->nonce.len)) {
		LOG(L_ERR, "sterman(): Unable to add PW_DIGEST_NONCE attribute\n");
		rc_avpair_free(send);
		return -7;
	}
	
	if (!rc_avpair_add(&send, PW_DIGEST_URI, _cred->uri.s, _cred->uri.len)) {
		LOG(L_ERR, "sterman(): Unable to add PW_DIGEST_URI attribute\n");
		rc_avpair_free(send);
		return -8;
	}
	if (!rc_avpair_add(&send, PW_DIGEST_METHOD, method.s, method.len)) {
		LOG(L_ERR, "sterman(): Unable to add PW_DIGEST_METHOD attribute\n");
		rc_avpair_free(send);
		return -9;
	}
	
	/* 
	 * Add the additional authentication fields according to the QOP.
	 */
	if (_cred->qop.qop_parsed == QOP_AUTH) {
		if (!rc_avpair_add(&send, PW_DIGEST_QOP, "auth", 4)) {
			LOG(L_ERR, "sterman(): Unable to add PW_DIGEST_QOP attribute\n");
			rc_avpair_free(send);
			return -10;
		}
		if (!rc_avpair_add(&send, PW_DIGEST_NONCE_COUNT, _cred->nc.s, _cred->nc.len)) {
			LOG(L_ERR, "sterman(): Unable to add PW_DIGEST_NONCE_COUNT attribute\n");
			rc_avpair_free(send);
			return -11;
		}
		if (!rc_avpair_add(&send, PW_DIGEST_CNONCE, _cred->cnonce.s, _cred->cnonce.len)) {
			LOG(L_ERR, "sterman(): Unable to add PW_DIGEST_CNONCE attribute\n");
			rc_avpair_free(send);
			return -12;
		}
	} else if (_cred->qop.qop_parsed == QOP_AUTHINT) {
		if (!rc_avpair_add(&send, PW_DIGEST_QOP, "auth-int", 8)) {
			LOG(L_ERR, "sterman(): Unable to add PW_DIGEST_QOP attribute\n");
			rc_avpair_free(send);
			return -13;
		}
		if (!rc_avpair_add(&send, PW_DIGEST_NONCE_COUNT, _cred->nc.s, _cred->nc.len)) {
			LOG(L_ERR, "sterman(): Unable to add PW_DIGEST_NONCE_COUNT attribute\n");
			rc_avpair_free(send);
			return -14;
		}
		if (!rc_avpair_add(&send, PW_DIGEST_CNONCE, _cred->cnonce.s, _cred->cnonce.len)) {
			LOG(L_ERR, "sterman(): Unable to add PW_DIGEST_CNONCE attribute\n");
			rc_avpair_free(send);
			return -15;
		}
		if (!rc_avpair_add(&send, PW_DIGEST_BODY_DIGEST, _cred->opaque.s, _cred->opaque.len)) {
			LOG(L_ERR, "sterman(): Unable to add PW_DIGEST_BODY_DIGEST attribute\n");
			rc_avpair_free(send);
			return -16;
		}
		
	} else  {
		/* send nothing for qop == "" */
	}

	/*
	 * Now put everything place all the previous attributes into the
	 * PW_DIGEST_ATTRIBUTES
	 */
	
	/*
	 *  Fix up Digest-Attributes issues see draft-sterman-aaa-sip-00
	 */
	for (vp = send; vp; vp = vp->next) {
		switch (vp->attribute) {
  		default:
			break;

			/* Fall thru the know values */
		case PW_DIGEST_REALM:
		case PW_DIGEST_NONCE:
		case PW_DIGEST_METHOD:
		case PW_DIGEST_URI:
		case PW_DIGEST_QOP:
		case PW_DIGEST_ALGORITHM:
		case PW_DIGEST_BODY_DIGEST:
		case PW_DIGEST_CNONCE:
		case PW_DIGEST_NONCE_COUNT:
		case PW_DIGEST_USER_NAME:
	
			/* overlapping! */
			memmove(&vp->strvalue[2], &vp->strvalue[0], vp->lvalue);
			vp->strvalue[0] = vp->attribute - PW_DIGEST_REALM + 1;
			vp->lvalue += 2;
			vp->strvalue[1] = vp->lvalue;
			vp->attribute = PW_DIGEST_ATTRIBUTES;
			break;
		}
	}

	/* Add the response... What to calculate against... */
	if (!rc_avpair_add(&send, PW_DIGEST_RESPONSE, _cred->response.s, _cred->response.len)) {
		LOG(L_ERR, "sterman(): Unable to add PW_DIGEST_RESPONSE attribute\n");
		rc_avpair_free(send);
		return -17;
	}

	/* Indicate the service type, Authenticate only in our case */
	service = service_type;
	if (!rc_avpair_add(&send, PW_SERVICE_TYPE, &service, 0)) {
		LOG(L_ERR, "sterman(): Unable to add PW_SERVICE_TYPE attribute\n");
		rc_avpair_free(send);
	 	return -18;
	}

	/* Add SIP URI as a check item */
	if (!rc_avpair_add(&send, PW_SIP_URI_USER, user.s, user.len)) {
		LOG(L_ERR, "sterman(): Unable to add PW_SIP_URI_USER attribute\n");
		rc_avpair_free(send);
	 	return -19;  	
	}
       
	/* Send request */
	if ((i = rc_auth(SIP_PORT, send, &received, msg)) == OK_RC) {
		DBG("radius_authorize_sterman(): Success\n");
		rc_avpair_free(send);

		     /* Make a copy of rpid if available */
		if ((vp = rc_avpair_get(received, PW_SIP_RPID))) {
			if (MAX_RPID_LEN < vp->lvalue) {
				LOG(L_ERR, "radius_authorize_sterman(): rpid buffer too small\n");
				return -20;
			}
			memcpy(_rpid->s, vp->strvalue, vp->lvalue);
			_rpid->len = vp->lvalue;
		}

		rc_avpair_free(received);
		return 1;
	} else {
		DBG("res: %d\n", i);
		DBG("radius_authorize_sterman(): Failure\n");
		rc_avpair_free(send);
		rc_avpair_free(received);
		return -21;
	}
}
コード例 #15
0
ファイル: functions.c プロジェクト: halan/kamailio
/*
 * Check from Radius if URI user given as argument belongs to a local user.
 * If so, loads AVPs based on reply items returned from Radius.
 */
int radius_does_uri_user_exist(struct sip_msg* _m, str user)
{
    static char msg[4096];
    VALUE_PAIR *send, *received;
    uint32_t service;
    int res, extra_cnt, offset, i;
    
    send = received = 0;
    
    if (!rc_avpair_add(rh, &send, uri_attrs[SA_USER_NAME].v,
		       user.s, user.len, 0)) {
	LM_ERR("in adding SA_USER_NAME\n");
	return -1;
    }
    
    service = uri_vals[UV_CALL_CHECK].v;
    if (!rc_avpair_add(rh, &send, uri_attrs[SA_SERVICE_TYPE].v,
		       &service, -1, 0)) {
	LM_ERR("in adding SA_SERVICE_TYPE <%u>\n", service);
	goto error;
    }

    /* Add extra attributes */
    extra_cnt = extra2strar(uri_extra, _m, val_arr);
    if (extra_cnt == -1) {
	LM_ERR("in getting values of group extra attributes\n");
	goto error;
    }
    offset = SA_STATIC_MAX;
    for (i = 0; i < extra_cnt; i++) {
	if (val_arr[i].len == -1) {
	    /* Add integer attribute */
	    ADD_EXTRA_AVPAIR(uri_attrs, offset+i,
			     &(val_arr[i].s), val_arr[i].len );
	} else {
	    /* Add string attribute */
	    ADD_EXTRA_AVPAIR(uri_attrs, offset+i,
			     val_arr[i].s, val_arr[i].len );
	}
    }

    if ((res = rc_auth(rh, 0, send, &received, msg)) == OK_RC) {
	LM_DBG("success\n");
	rc_avpair_free(send);
	generate_avps(uri_attrs, received);
	rc_avpair_free(received);
	return 1;
    } else {
	rc_avpair_free(send);
	rc_avpair_free(received);
#ifdef REJECT_RC
	if (res == REJECT_RC) {
	    LM_DBG("rejected\n");
	    return -1;
	} else {
	    LM_ERR("failure\n");
	    return -2;
	}
#else
	LM_DBG("failure\n");
	return -1;
#endif
    }

 error:
    rc_avpair_free(send);
    return -1;
}
コード例 #16
0
ファイル: sterman.c プロジェクト: AndreiPlesa/kamailio
/*
 * This function creates and submits radius authentication request as per
 * draft-sterman-aaa-sip-00.txt.  In addition, _user parameter is included
 * in the request as value of a SER specific attribute type SIP-URI-User,
 * which can be be used as a check item in the request.  Service type of
 * the request is Authenticate-Only.
 */
int radius_authorize_sterman(struct sip_msg* _msg, dig_cred_t* _cred, str* _method, str* _user) 
{
	static char msg[4096];
	VALUE_PAIR *send, *received;
	uint32_t service;
	str method, user, user_name;
	str *ruri;
	int extra_cnt, offset, i;
		
	send = received = 0;

	if (!(_cred && _method && _user)) {
		LM_ERR("invalid parameter value\n");
		return -1;
	}

	method = *_method;
	user = *_user;
	
	/*
	 * Add all the user digest parameters according to the qop defined.
	 * Most devices tested only offer support for the simplest digest.
	 */
	if (_cred->username.domain.len || !append_realm_to_username) {
		if (!rc_avpair_add(rh, &send, attrs[A_USER_NAME].v, _cred->username.whole.s, _cred->username.whole.len, 0)) {
			LM_ERR("unable to add User-Name attribute\n");
			goto err;
		}
	} else {
		user_name.len = _cred->username.user.len + _cred->realm.len + 1;
		user_name.s = pkg_malloc(user_name.len);
		if (!user_name.s) {
			LM_ERR("no pkg memory left\n");
			return -3;
		}
		memcpy(user_name.s, _cred->username.whole.s, _cred->username.whole.len);
		user_name.s[_cred->username.whole.len] = '@';
		memcpy(user_name.s + _cred->username.whole.len + 1, _cred->realm.s,
			_cred->realm.len);
		if (!rc_avpair_add(rh, &send, attrs[A_USER_NAME].v, user_name.s,
		user_name.len, 0)) {
			LM_ERR("unable to add User-Name attribute\n");
			pkg_free(user_name.s);
			goto err;
		}
		pkg_free(user_name.s);
	}

	if (!rc_avpair_add(rh, &send, attrs[A_DIGEST_USER_NAME].v, 
	_cred->username.whole.s, _cred->username.whole.len, 0)) {
		LM_ERR("unable to add Digest-User-Name attribute\n");
		goto err;
	}

	if (!rc_avpair_add(rh, &send, attrs[A_DIGEST_REALM].v, _cred->realm.s,
	_cred->realm.len, 0)) {
		LM_ERR("unable to add Digest-Realm attribute\n");
		goto err;
	}
	if (!rc_avpair_add(rh, &send, attrs[A_DIGEST_NONCE].v, _cred->nonce.s,
	_cred->nonce.len, 0)) {
		LM_ERR("unable to add Digest-Nonce attribute\n");
		goto err;
	}

	if (use_ruri_flag < 0 || isflagset(_msg, use_ruri_flag) != 1) {
		ruri = &_cred->uri;
	} else {
		ruri = GET_RURI(_msg);
	}
	if (!rc_avpair_add(rh, &send, attrs[A_DIGEST_URI].v, ruri->s,
	ruri->len, 0)) {
		LM_ERR("unable to add Digest-URI attribute\n");
		goto err;
	}

	if (!rc_avpair_add(rh, &send, attrs[A_DIGEST_METHOD].v, method.s,
	method.len, 0)) {
		LM_ERR("unable to add Digest-Method attribute\n");
		goto err;
	}
	
	/* 
	 * Add the additional authentication fields according to the QOP.
	 */
	if (_cred->qop.qop_parsed == QOP_AUTH) {
		if (!rc_avpair_add(rh, &send, attrs[A_DIGEST_QOP].v, "auth", 4, 0)) {
			LM_ERR("unable to add Digest-QOP attribute\n");
			goto err;
		}
		if (!rc_avpair_add(rh, &send, attrs[A_DIGEST_NONCE_COUNT].v, 
		_cred->nc.s, _cred->nc.len, 0)) {
			LM_ERR("unable to add Digest-CNonce-Count attribute\n");
			goto err;
		}
		if (!rc_avpair_add(rh, &send, attrs[A_DIGEST_CNONCE].v, 
		_cred->cnonce.s, _cred->cnonce.len, 0)) {
			LM_ERR("unable to add Digest-CNonce attribute\n");
			goto err;
		}
	} else if (_cred->qop.qop_parsed == QOP_AUTHINT) {
		if (!rc_avpair_add(rh, &send, attrs[A_DIGEST_QOP].v,
		"auth-int", 8, 0)) {
			LM_ERR("unable to add Digest-QOP attribute\n");
			goto err;
		}
		if (!rc_avpair_add(rh, &send, attrs[A_DIGEST_NONCE_COUNT].v,
		_cred->nc.s, _cred->nc.len, 0)) {
			LM_ERR("unable to add Digest-Nonce-Count attribute\n");
			goto err;
		}
		if (!rc_avpair_add(rh, &send, attrs[A_DIGEST_CNONCE].v,
		_cred->cnonce.s, _cred->cnonce.len, 0)) {
			LM_ERR("unable to add Digest-CNonce attribute\n");
			goto err;
		}
		if (!rc_avpair_add(rh, &send, attrs[A_DIGEST_BODY_DIGEST].v, 
		_cred->opaque.s, _cred->opaque.len, 0)) {
			LM_ERR("unable to add Digest-Body-Digest attribute\n");
			goto err;
		}
		
	} else  {
		/* send nothing for qop == "" */
	}

	/* Add the response... What to calculate against... */
	if (!rc_avpair_add(rh, &send, attrs[A_DIGEST_RESPONSE].v, 
	_cred->response.s, _cred->response.len, 0)) {
		LM_ERR("unable to add Digest-Response attribute\n");
		goto err;
	}

	/* Indicate the service type, Authenticate only in our case */
	service = vals[V_SIP_SESSION].v;
	if (!rc_avpair_add(rh, &send, attrs[A_SERVICE_TYPE].v, &service, -1, 0)) {
		LM_ERR("unable to add Service-Type attribute\n");
		goto err;
	}

	/* Add SIP URI as a check item */
	if (!rc_avpair_add(rh,&send,attrs[A_SIP_URI_USER].v,user.s,user.len,0)) {
		LM_ERR("unable to add Sip-URI-User attribute\n");
		goto err;
	}

	if (attrs[A_CISCO_AVPAIR].n != NULL) {
		if (add_cisco_vsa(&send, _msg)) {
			goto err;
		}
	}

	/* Add extra attributes */
	extra_cnt = extra2strar(auth_extra, _msg, val_arr);
	if (extra_cnt == -1) {
	    LM_ERR("in getting values of extra attributes\n");
	    goto err;
	}
	offset = A_MAX;
	for (i = 0; i < extra_cnt; i++) {
	    if (val_arr[i].len == -1) {
		/* Add integer attribute */
		ADD_EXTRA_AVPAIR(attrs, offset+i,
				 &(val_arr[i].s), val_arr[i].len );
	    } else {
		/* Add string attribute */
		ADD_EXTRA_AVPAIR(attrs, offset+i,
				 val_arr[i].s, val_arr[i].len );
	    }
	}

	/* Send request */
	if ((i = rc_auth(rh, SIP_PORT, send, &received, msg)) == OK_RC) {
		LM_DBG("Success\n");
		rc_avpair_free(send);
		send = 0;

		generate_avps(received);

		rc_avpair_free(received);
		return 1;
	} else {
#ifdef REJECT_RC
                if (i == REJECT_RC) {
                        LM_DBG("Failure\n");
                        goto err;
                }
#endif 
		LM_ERR("authorization failed. RC auth returned %d\n", i);
	}

 err:
	if (send) rc_avpair_free(send);
	if (received) rc_avpair_free(received);
	return -1;
}
コード例 #17
0
ファイル: call_radius.c プロジェクト: BHYCHIK/exim
int
auth_call_radius(const uschar *s, uschar **errptr)
{
uschar *user;
const uschar *radius_args = s;
int result;
int sep = 0;

#ifdef RADIUS_LIB_RADLIB
  struct rad_handle *h;
#else
  #ifdef RADIUS_LIB_RADIUSCLIENTNEW
    rc_handle *h;
  #endif
  VALUE_PAIR *send = NULL;
  VALUE_PAIR *received;
  unsigned int service = PW_AUTHENTICATE_ONLY;
  char msg[4096];
#endif


user = string_nextinlist(&radius_args, &sep, big_buffer, big_buffer_size);
if (user == NULL) user = US"";

DEBUG(D_auth) debug_printf("Running RADIUS authentication for user \"%s\" "
               "and \"%s\"\n", user, radius_args);

*errptr = NULL;


/* Authenticate using the radiusclient library */

#ifndef RADIUS_LIB_RADLIB

rc_openlog("exim");

#ifdef RADIUS_LIB_RADIUSCLIENT
if (rc_read_config(RADIUS_CONFIG_FILE) != 0)
  *errptr = string_sprintf("RADIUS: can't open %s", RADIUS_CONFIG_FILE);

else if (rc_read_dictionary(rc_conf_str("dictionary")) != 0)
  *errptr = string_sprintf("RADIUS: can't read dictionary");

else if (rc_avpair_add(&send, PW_USER_NAME, user, 0) == NULL)
  *errptr = string_sprintf("RADIUS: add user name failed\n");

else if (rc_avpair_add(&send, PW_USER_PASSWORD, CS radius_args, 0) == NULL)
  *errptr = string_sprintf("RADIUS: add password failed\n");

else if (rc_avpair_add(&send, PW_SERVICE_TYPE, &service, 0) == NULL)
  *errptr = string_sprintf("RADIUS: add service type failed\n");

#else  /* RADIUS_LIB_RADIUSCLIENT unset => RADIUS_LIB_RADIUSCLIENT2 */

if ((h = rc_read_config(RADIUS_CONFIG_FILE)) == NULL)
  *errptr = string_sprintf("RADIUS: can't open %s", RADIUS_CONFIG_FILE);

else if (rc_read_dictionary(h, rc_conf_str(h, "dictionary")) != 0)
  *errptr = string_sprintf("RADIUS: can't read dictionary");

else if (rc_avpair_add(h, &send, PW_USER_NAME, user, Ustrlen(user), 0) == NULL)
  *errptr = string_sprintf("RADIUS: add user name failed\n");

else if (rc_avpair_add(h, &send, PW_USER_PASSWORD, CS radius_args,
    Ustrlen(radius_args), 0) == NULL)
  *errptr = string_sprintf("RADIUS: add password failed\n");

else if (rc_avpair_add(h, &send, PW_SERVICE_TYPE, &service, 0, 0) == NULL)
  *errptr = string_sprintf("RADIUS: add service type failed\n");

#endif  /* RADIUS_LIB_RADIUSCLIENT */

if (*errptr != NULL)
  {
  DEBUG(D_auth) debug_printf("%s\n", *errptr);
  return ERROR;
  }

#ifdef RADIUS_LIB_RADIUSCLIENT
result = rc_auth(0, send, &received, msg);
#else
result = rc_auth(h, 0, send, &received, msg);
#endif

DEBUG(D_auth) debug_printf("RADIUS code returned %d\n", result);

switch (result)
  {
  case OK_RC:
  return OK;

  case REJECT_RC:
  case ERROR_RC:
  return FAIL;

  case TIMEOUT_RC:
  *errptr = US"RADIUS: timed out";
  return ERROR;

  default:
  case BADRESP_RC:
  *errptr = string_sprintf("RADIUS: unexpected response (%d)", result);
  return ERROR;
  }

#else  /* RADIUS_LIB_RADLIB is set */

/* Authenticate using the libradius library */

h = rad_auth_open();
if (h == NULL)
  {
  *errptr = string_sprintf("RADIUS: can't initialise libradius");
  return ERROR;
  }
if (rad_config(h, RADIUS_CONFIG_FILE) != 0 ||
    rad_create_request(h, RAD_ACCESS_REQUEST) != 0 ||
    rad_put_string(h, RAD_USER_NAME, CS user) != 0 ||
    rad_put_string(h, RAD_USER_PASSWORD, CS radius_args) != 0 ||
    rad_put_int(h, RAD_SERVICE_TYPE, RAD_AUTHENTICATE_ONLY) != 0 ||
    rad_put_string(h, RAD_NAS_IDENTIFIER, CS primary_hostname) != 0)
  {
  *errptr = string_sprintf("RADIUS: %s", rad_strerror(h));
  result = ERROR;
  }
else
  {
  result = rad_send_request(h);

  switch(result)
    {
    case RAD_ACCESS_ACCEPT:
    result = OK;
    break;

    case RAD_ACCESS_REJECT:
    result = FAIL;
    break;

    case -1:
    *errptr = string_sprintf("RADIUS: %s", rad_strerror(h));
    result = ERROR;
    break;

    default:
    *errptr = string_sprintf("RADIUS: unexpected response (%d)", result);
    result= ERROR;
    break;
    }
  }

if (*errptr != NULL) DEBUG(D_auth) debug_printf("%s\n", *errptr);
rad_close(h);
return result;

#endif  /* RADIUS_LIB_RADLIB */
}
コード例 #18
0
ファイル: mod_rad_auth.c プロジェクト: PauloFer1/FreeSWITCH
int radius_auth(switch_channel_t *channel, char* called_number, char* username, char* password , char* auth_result/*, char* biling_model, char* credit_amount, char* currency, char* preffered_lang*/)
{
	int result = OK_RC;
	VALUE_PAIR *send = NULL;
	VALUE_PAIR *received = NULL;
	VALUE_PAIR 	*service_vp;
	DICT_ATTR   *pda;
	CONFIG_VSAS* PCONFIGVSAS = NULL;
	char *default_realm = NULL;
	rc_handle *rh = NULL;
	int attrid  =0;

	char msg[STR_LENGTH * 10 + 1];
	char username_realm[STR_LENGTH + 1];
	char value[STR_LENGTH + 1];
	int integer;

	memset(msg, 0, STR_LENGTH * 10);
	memset(username_realm, 0, STR_LENGTH);
	
	send = NULL;
	


	do
	{
		
#if EMBENDED_CONFIG

		CONFIG_CLIENT* PCONFIGCLIENT = CONFIGCLIENT;
		
		rh = rc_new();
		if (rh == NULL) 
		{
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ERROR: Failed to allocate initial structure.\n");
			result = ERROR_RC;
			break;
		}
		
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "allocate initial structure.\n");
	
		/* Initialize the config structure */
	
		rh = rc_config_init(rh);
		if (rh == NULL)
		{
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,"ERROR: Failed to initialze configuration.\n");
			result = ERROR_RC;
			break;
		}
		
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,"initialzed configuration.\n");
	
		while(PCONFIGCLIENT)
		{
			//if (rc_add_config(rh, "auth_order", "radius", "config", 0) != 0) 
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "set %s := %s.\n", PCONFIGCLIENT->name, PCONFIGCLIENT->value);
			if (rc_add_config(rh, PCONFIGCLIENT->name, PCONFIGCLIENT->value, "config", 0) != 0) 
			{
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ERROR: Unable to set %s := %s.\n", PCONFIGCLIENT->name, PCONFIGCLIENT->value);
				
				result = ERROR_RC;
				break;
			}
			
			PCONFIGCLIENT = PCONFIGCLIENT->pNext;
		}
		
		if (result == ERROR_RC)
			break;

		
#else
		if ((rh = rc_read_config(!rc_config_file ? RC_CONFIG_FILE : rc_config_file)) == NULL)
		{
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error loading radius config file\n");
			
			result = ERROR_RC;
			break;
		}
		
#endif

		if (rc_read_dictionary(rh, rc_conf_str(rh, "dictionary")) != 0)
		{
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error loading radius dictionary\n");
			
			result = ERROR_RC;
			break;
		}
		
		default_realm = rc_conf_str(rh, "default_realm");
		if (default_realm == NULL)
		{
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "default_realm is null object.\n");
			result = ERROR_RC;
			break;
		}
		
		strncpy(username_realm, username, sizeof(username_realm));

		if ((strchr(username_realm, '@') == NULL) && default_realm &&
		    (*default_realm != '\0'))
		{
			strncat(username_realm, "@", sizeof(username_realm)-strlen(username_realm)-1);
			strncat(username_realm, default_realm, sizeof(username_realm)-strlen(username_realm)-1);
		}
		
	
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,
			"... radius: User-Name: %s\n", username);
		if (rc_avpair_add(rh, &send, PW_USER_NAME, username_realm, -1, 0)== NULL)
		{
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "An Error occured during rc_avpair_add : username\n");
			result = ERROR_RC;
			break;
		}
		
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,
			"... radius: User-Password: %s\n", password);
		if (rc_avpair_add(rh, &send, PW_USER_PASSWORD, password, -1, 0) == NULL)
		{
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "An Error occured during rc_avpair_add : password\n");
			result = ERROR_RC;
			break;
		}
		
		if (!called_number || strcmp(called_number, "") == 0)
		{
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,
				"... radius: Called-station-Id is empty, ignoring...\n");
		}
		else
		{
					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,
				"... radius: Called-station-Id: %s\n", called_number);
			if (rc_avpair_add(rh, &send, 30, called_number, -1, 0) == NULL)
			{
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "An Error occured during rc_avpair_add : Called-station-Id\n");
				result = ERROR_RC;
				break;
			}
		}

		
		PCONFIGVSAS = CONFIGVSAS;
	
		while(PCONFIGVSAS)
		{
			if (PCONFIGVSAS->direction == 1)
			{
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Handle attribute: %s\n", PCONFIGVSAS->name	);
				
				memset(value, 0, STR_LENGTH);
				GetValue(channel, PCONFIGVSAS, value);
				
				if (PCONFIGVSAS->pec != 0)
					attrid = PCONFIGVSAS->id | (PCONFIGVSAS->pec << 16);
				else
					attrid = PCONFIGVSAS->id ;
					
				pda = rc_dict_getattr(rh, attrid);
				
				if (pda == NULL)
				{
					result = ERROR_RC;
					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unknown attribute: key:%s, not found in dictionary\n", PCONFIGVSAS->name);
					break;	
				}
				
				if (PCONFIGVSAS->pec != 0 && rc_dict_getvend(rh, PCONFIGVSAS->pec) == NULL)
				{
					result = ERROR_RC;
					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unknown vendor specific id: key:%s, id:%dnot found in dictionary\n", PCONFIGVSAS->name, PCONFIGVSAS->pec);
					break;	
				}
				
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "... dictionary data: id:%d, vendor id:%d, attr type:%d, attr name:%s (%d)\n", PCONFIGVSAS->id, PCONFIGVSAS->pec, pda->type, pda->name, attrid);
				
				switch(pda->type)
				{
					case PW_TYPE_STRING:
						switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "... radius: key:%s, value:%s (%s) as string\n", PCONFIGVSAS->name, PCONFIGVSAS->value, value);
						if (rc_avpair_add(rh, &send, PCONFIGVSAS->id, value, -1, PCONFIGVSAS->pec) == NULL)
						{
							switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "An Error occured during rc_avpair_add : %s\n", PCONFIGVSAS->name);
							result = ERROR_RC;
							break;
						}
						break;
						
					//case PW_TYPE_DATE:
					case PW_TYPE_INTEGER:
						integer = atoi(value);
						switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "... radius: key:%s, value:%s (%d) as integer\n", PCONFIGVSAS->name, PCONFIGVSAS->value, integer);
						
						
						if (rc_avpair_add(rh, &send, PCONFIGVSAS->id, &integer, -1, PCONFIGVSAS->pec) == NULL)
						{
							switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "An Error occured during rc_avpair_add : %s\n", PCONFIGVSAS->name);
							result = ERROR_RC;
							break;
						}
						break;
					case PW_TYPE_IPADDR:
						integer = rc_get_ipaddr(value);
						switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "... radius: key:%s, value:%s (%d) as ipaddr\n", PCONFIGVSAS->name, PCONFIGVSAS->value, integer);
						
						
						if (rc_avpair_add(rh, &send, PCONFIGVSAS->id, &integer, -1, PCONFIGVSAS->pec) == NULL)
						{
							switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "An Error occured during rc_avpair_add : %s\n", PCONFIGVSAS->name);
							result = ERROR_RC;
							break;
						}
						break;						
						
					default:
						switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unknown attribute type: key:%s, type %d\n", PCONFIGVSAS->name, pda->type);
						break;
				}
			}
			
			PCONFIGVSAS = PCONFIGVSAS->pNext;
		}

		
		if (result != ERROR_RC)
		{
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "sending radius packet ...\n"	);
			result = rc_auth(rh, 0, send, &received, msg);
		
	
			if (result == OK_RC)
			{
					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,
					"RADIUS Authentication OK\n");
					
					strcpy(auth_result, "OK");
			}
			else
			{
					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,
					" RADIUS Authentication failure (RC=%d)\n", 
					result);
					
					strcpy(auth_result, "NOK");
			}
			
			
			
			PCONFIGVSAS = CONFIGVSAS;
		
			while(PCONFIGVSAS)
			{
				if (PCONFIGVSAS->direction == 0)
				{
					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Handle attribute: %s\n", PCONFIGVSAS->name	);
					if ((service_vp = rc_avpair_get(received, PCONFIGVSAS->id, PCONFIGVSAS->pec)) != NULL)
					{
						switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "\tattribute (%s) found in radius packet\n", PCONFIGVSAS->name);
						switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "\tset variable %s := %s\n", PCONFIGVSAS->value, service_vp->strvalue);
						
						switch_channel_set_variable(channel, PCONFIGVSAS->value, service_vp->strvalue);
					}
					else
					{
						switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "\tNo found out attribute id: %d, pec:%d, (%s)\n", PCONFIGVSAS->id, PCONFIGVSAS->pec, PCONFIGVSAS->name	);
					}
				}
				
				PCONFIGVSAS = PCONFIGVSAS->pNext;
			}
		}
		else
		{
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "abort sending radius packet.\n"	);
			break;
		}
	
	} while(1 == 0);

	if (result == ERROR_RC)
	{
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,
				"An error occured during RADIUS Authentication(RC=%d)\n", 
				result);
	}
	
	free_radius_auth_value_pair(send, received, rh);
	
	return result;
}
コード例 #19
0
ファイル: mod_rad_auth.c プロジェクト: PauloFer1/FreeSWITCH
int radius_auth_test(switch_channel_t *channel, char* username1, char* passwd1, char* auth_result, char* biling_model, char* credit_amount, char* currency, char* preffered_lang)
{
	int             result;
	char		username[128];
	char            passwd[AUTH_PASS_LEN + 1];
	VALUE_PAIR 	*send, *received;
	uint32_t		service;
	char 		msg[4096], username_realm[256];
	char		*default_realm;
	rc_handle	*rh;

	strcpy(username, "123");
	strcpy(passwd, "123");

	if ((rh = rc_read_config(RC_CONFIG_FILE)) == NULL)
		return ERROR_RC;

	if (rc_read_dictionary(rh, rc_conf_str(rh, "dictionary")) != 0)
		return ERROR_RC;

	default_realm = rc_conf_str(rh, "default_realm");


	send = NULL;

	/*
	 * Fill in User-Name
	 */

	strncpy(username_realm, username, sizeof(username_realm));

	/* Append default realm */
	if ((strchr(username_realm, '@') == NULL) && default_realm &&
	    (*default_realm != '\0'))
	{
		strncat(username_realm, "@", sizeof(username_realm)-strlen(username_realm)-1);
		strncat(username_realm, default_realm, sizeof(username_realm)-strlen(username_realm)-1);
	}

	if (rc_avpair_add(rh, &send, PW_USER_NAME, username_realm, -1, 0) == NULL)
		return ERROR_RC;

	/*
	 * Fill in User-Password
	 */

	if (rc_avpair_add(rh, &send, PW_USER_PASSWORD, passwd, -1, 0) == NULL)
		return ERROR_RC;

	/*
	 * Fill in Service-Type
	 */

	service = PW_AUTHENTICATE_ONLY;
	if (rc_avpair_add(rh, &send, PW_SERVICE_TYPE, &service, -1, 0) == NULL)
		return ERROR_RC;

	result = rc_auth(rh, 0, send, &received, msg);

	if (result == OK_RC)
	{
		fprintf(stderr, "\"%s\" RADIUS Authentication OK\n", username);
	}
	else
	{
		fprintf(stderr, "\"%s\" RADIUS Authentication failure (RC=%i)\n", username, result);
	}

	return result;

}
コード例 #20
0
ファイル: sterman.c プロジェクト: 4N7HR4X/kamailio
/*
 * This function creates and submits radius authentication request as per
 * draft-sterman-aaa-sip-00.txt.  In addition, _user parameter is included
 * in the request as value of a SER specific attribute type SIP-URI-User,
 * which can be be used as a check item in the request.  Service type of
 * the request is Authenticate-Only.
 */
int radius_authorize_sterman(VALUE_PAIR** received, struct sip_msg* _msg, dig_cred_t* _cred, str* _method, str* _user) 
{
	static char msg[4096];
	VALUE_PAIR *send;
	UINT4 service, ser_service_type;
	str method, user, user_name;
	str *ruri;
	int i;
	
	send = 0;

	if (!(_cred && _method && _user)) {
		LOG(L_ERR, "radius_authorize_sterman(): Invalid parameter value\n");
		return -1;
	}

	method = *_method;
	user = *_user;
	
	/*
	 * Add all the user digest parameters according to the qop defined.
	 * Most devices tested only offer support for the simplest digest.
	 */
	if (_cred->username.domain.len) {
	        if (!rc_avpair_add(rh, &send, ATTRID(attrs[A_USER_NAME].v), 
				   _cred->username.whole.s, _cred->username.whole.len, 
			           VENDOR(attrs[A_USER_NAME].v))) {
			LOG(L_ERR, "radius_authorize_sterman(): Unable to add User-Name attribute\n");
			goto err;
		}
	} else {
		user_name.len = _cred->username.user.len + _cred->realm.len + 1;
		user_name.s = pkg_malloc(user_name.len);
		if (!user_name.s) {
			LOG(L_ERR, "radius_authorize_sterman(): No memory left\n");
			return -3;
		}
		memcpy(user_name.s, _cred->username.whole.s, _cred->username.whole.len);
		user_name.s[_cred->username.whole.len] = '@';
		memcpy(user_name.s + _cred->username.whole.len + 1, _cred->realm.s, _cred->realm.len);
		if (!rc_avpair_add(rh, &send, ATTRID(attrs[A_USER_NAME].v), 
				   user_name.s, user_name.len, 
				   VENDOR(attrs[A_USER_NAME].v))) {
			LOG(L_ERR, "sterman(): Unable to add User-Name attribute\n");
			pkg_free(user_name.s);
			goto err;
		}
		pkg_free(user_name.s);
	}

	if (!rc_avpair_add(rh, &send, ATTRID(attrs[A_DIGEST_USER_NAME].v), 
			   _cred->username.whole.s, _cred->username.whole.len, 
			   VENDOR(attrs[A_DIGEST_USER_NAME].v))) {
		LOG(L_ERR, "sterman(): Unable to add Digest-User-Name attribute\n");
		goto err;
	}

	if (!rc_avpair_add(rh, &send, ATTRID(attrs[A_DIGEST_REALM].v), 
			   _cred->realm.s, _cred->realm.len, 
			   VENDOR(attrs[A_DIGEST_REALM].v))) {
		LOG(L_ERR, "sterman(): Unable to add Digest-Realm attribute\n");
		goto err;
	}
	if (!rc_avpair_add(rh, &send, ATTRID(attrs[A_DIGEST_NONCE].v), 
			   _cred->nonce.s, _cred->nonce.len, 
			   VENDOR(attrs[A_DIGEST_NONCE].v))) {
		LOG(L_ERR, "sterman(): Unable to add Digest-Nonce attribute\n");
		goto err;
	}
	
	if (use_ruri_flag < 0 || isflagset(_msg, use_ruri_flag) != 1) {
		ruri = &_cred->uri;
	} else {
		ruri = GET_RURI(_msg);
	}
	if (!rc_avpair_add(rh, &send, ATTRID(attrs[A_DIGEST_URI].v), 
			   ruri->s, ruri->len, 
			   VENDOR(attrs[A_DIGEST_URI].v))) {
		LOG(L_ERR, "sterman(): Unable to add Digest-URI attribute\n");
		goto err;
	}
		
	if (!rc_avpair_add(rh, &send, ATTRID(attrs[A_DIGEST_METHOD].v),
			   method.s, method.len, 
			   VENDOR(attrs[A_DIGEST_METHOD].v))) {
	        LOG(L_ERR, "sterman(): Unable to add Digest-Method attribute\n");
		goto err;
	}
	
	/* 
	 * Add the additional authentication fields according to the QOP.
	 */
	if (_cred->qop.qop_parsed == QOP_AUTH) {
		if (!rc_avpair_add(rh, &send, ATTRID(attrs[A_DIGEST_QOP].v), "auth", 4,
				   VENDOR(attrs[A_DIGEST_QOP].v))) {
			LOG(L_ERR, "sterman(): Unable to add Digest-QOP attribute\n");
			goto err;
		}
		if (!rc_avpair_add(rh, &send, ATTRID(attrs[A_DIGEST_NONCE_COUNT].v), 
				   _cred->nc.s, _cred->nc.len,
				   VENDOR(attrs[A_DIGEST_NONCE_COUNT].v))) {
			LOG(L_ERR, "sterman(): Unable to add Digest-CNonce-Count attribute\n");
			goto err;
		}
		if (!rc_avpair_add(rh, &send, ATTRID(attrs[A_DIGEST_CNONCE].v), 
				   _cred->cnonce.s, _cred->cnonce.len,
				   VENDOR(attrs[A_DIGEST_CNONCE].v))) {
			LOG(L_ERR, "sterman(): Unable to add Digest-CNonce attribute\n");
			goto err;
		}
	} else if (_cred->qop.qop_parsed == QOP_AUTHINT) {
	        if (!rc_avpair_add(rh, &send, ATTRID(attrs[A_DIGEST_QOP].v), "auth-int", 8, 
				   VENDOR(attrs[A_DIGEST_QOP].v))) {
		        LOG(L_ERR, "sterman(): Unable to add Digest-QOP attribute\n");
			goto err;
		}
		if (!rc_avpair_add(rh, &send, ATTRID(attrs[A_DIGEST_NONCE_COUNT].v), 
				   _cred->nc.s, _cred->nc.len, 
				   VENDOR(attrs[A_DIGEST_NONCE_COUNT].v))) {
			LOG(L_ERR, "sterman(): Unable to add Digest-Nonce-Count attribute\n");
			goto err;
		}
		if (!rc_avpair_add(rh, &send, ATTRID(attrs[A_DIGEST_CNONCE].v), 
				   _cred->cnonce.s, _cred->cnonce.len, 
				   VENDOR(attrs[A_DIGEST_CNONCE].v))) {
			LOG(L_ERR, "sterman(): Unable to add Digest-CNonce attribute\n");
			goto err;
		}
		if (!rc_avpair_add(rh, &send, ATTRID(attrs[A_DIGEST_BODY_DIGEST].v), 
				   _cred->opaque.s, _cred->opaque.len, 
				   VENDOR(attrs[A_DIGEST_BODY_DIGEST].v))) {
			LOG(L_ERR, "sterman(): Unable to add Digest-Body-Digest attribute\n");
			goto err;
		}
		
	} else  {
		/* send nothing for qop == "" */
	}

	/* Add the response... What to calculate against... */
	if (!rc_avpair_add(rh, &send, ATTRID(attrs[A_DIGEST_RESPONSE].v), 
			   _cred->response.s, _cred->response.len, 
			   VENDOR(attrs[A_DIGEST_RESPONSE].v))) {
		LOG(L_ERR, "sterman(): Unable to add Digest-Response attribute\n");
		goto err;
	}

	/* Indicate the service type, Authenticate only in our case */
	service = vals[V_SIP_SESSION].v;
	if (!rc_avpair_add(rh, &send, ATTRID(attrs[A_SERVICE_TYPE].v), 
			   &service, -1, 
			   VENDOR(attrs[A_SERVICE_TYPE].v))) {
	        LOG(L_ERR, "sterman(): Unable to add Service-Type attribute\n");
		goto err;
	}

	/* Indicate the service type, Authenticate only in our case */
	ser_service_type = vals[V_DIGEST_AUTHENTICATION].v;
	if (!rc_avpair_add(rh, &send, ATTRID(attrs[A_SER_SERVICE_TYPE].v), 
			   &ser_service_type, -1, 
			   VENDOR(attrs[A_SER_SERVICE_TYPE].v))) {
		LOG(L_ERR, "sterman(): Unable to add SER-Service-Type attribute\n");
		goto err;
	}

	/* Add SIP URI as a check item */
	if (!rc_avpair_add(rh, &send, ATTRID(attrs[A_SER_URI_USER].v), 
			   user.s, user.len, 
			   VENDOR(attrs[A_SER_URI_USER].v))) {
		LOG(L_ERR, "sterman(): Unable to add Sip-URI-User attribute\n");
		goto err;
	}

	if (attrs[A_CISCO_AVPAIR].n != NULL) {
		if (add_cisco_vsa(&send, _msg)) {
			goto err;
		}
	}

	/* Send request */
	if ((i = rc_auth(rh, SIP_PORT, send, received, msg)) == OK_RC) {
		DBG("radius_authorize_sterman(): Success\n");
		rc_avpair_free(send);
		send = 0;
		return 1;
	} else {
		DBG("radius_authorize_sterman(): Failure\n");
		goto err;
	}

 err:
	if (send) rc_avpair_free(send);	
	return -1;
}
コード例 #21
0
ファイル: overlord.c プロジェクト: carriercomm/zerod
/**
 * Authenticate and set client info.
 * @param[in] sess Client session.
 * @return Zero on success (or one of *_RC).
 */
static int session_authenticate(struct zsession *sess)
{
    int ret = OTHER_RC;
    VALUE_PAIR *request_attrs = NULL, *response_attrs = NULL, *attrs = NULL;
    char msg[8192]; // WARNING: libfreeradius-client has unsafe working with this buffer.
    rc_handle *rh = zinst()->radh;
    struct in_addr ip_addr;
    char ip_str[INET_ADDRSTRLEN];
    struct zcrules rules;

    crules_init(&rules);

    ip_addr.s_addr = htonl(sess->ip);
    if (unlikely(NULL == inet_ntop(AF_INET, &ip_addr, ip_str, sizeof(ip_str)))) {
        goto end;
    }

    if (unlikely(NULL == rc_avpair_add(rh, &request_attrs, PW_USER_NAME, ip_str, -1, 0))) {
        goto end;
    }
    if (unlikely(NULL == rc_avpair_add(rh, &request_attrs, PW_USER_PASSWORD, "", -1, 0))) {
        goto end;
    }
    if (unlikely(NULL == rc_avpair_add(rh, &request_attrs, PW_NAS_IDENTIFIER, zcfg()->radius_nas_identifier, -1, 0))) {
        goto end;
    }
    if (unlikely(NULL == rc_avpair_add(rh, &request_attrs, PW_CALLING_STATION_ID, ip_str, -1, 0))) {
        goto end;
    }

    ret = rc_auth(rh, 0, request_attrs, &response_attrs, msg);
    if (OK_RC != ret) {
        ZERO_LOG(LOG_ERR, "Session authentication failed for %s (code:%d)", ip_str, ret);
        goto end;
    }

    attrs = response_attrs;
    while (likely(NULL != attrs)) {
        switch (attrs->attribute) {
            case PW_FILTER_ID:
                crules_parse(&rules, attrs->strvalue);
                break;
            case PW_SESSION_TIMEOUT:
                atomic_store_explicit(&sess->max_duration, SEC2USEC(attrs->lvalue), memory_order_release);
                break;
            case PW_ACCT_INTERIM_INTERVAL:
                atomic_store_explicit(&sess->acct_interval, SEC2USEC(attrs->lvalue), memory_order_release);
                break;
        }
        attrs = attrs->next;
    }

    if (likely(rules.have.user_id && rules.have.login)) {
        struct zclient *client = sess->client;

        client_db_find_or_set_id(zinst()->client_db, rules.user_id, &client);
        if (client != sess->client) {
            // found
            pthread_rwlock_wrlock(&sess->lock_client);
            atomic_fetch_add_explicit(&client->refcnt, 1, memory_order_relaxed);
            client_release(sess->client);
            sess->client = client;
            client_session_add(sess->client, sess);
            pthread_rwlock_unlock(&sess->lock_client);
        } else {
            client_apply_rules(sess->client, &rules);
        }

        atomic_fetch_sub_explicit(&zinst()->unauth_sessions_cnt, 1, memory_order_release);

        // log successful authentication
        {
            UT_string rules_str;
            utstring_init(&rules_str);
            utstring_reserve(&rules_str, 1024);

            attrs = response_attrs;
            while (likely(NULL != attrs)) {
                switch (attrs->attribute) {
                    case PW_FILTER_ID:
                        utstring_printf(&rules_str, " %s", attrs->strvalue);
                        break;
                    default:
                        break;
                }
                attrs = attrs->next;
            }

            zero_syslog(LOG_INFO, "Authenticated session %s (rules:%s)", ip_str, utstring_body(&rules_str));
            utstring_done(&rules_str);
        }
    } else {
        ret = OTHER_RC;
        ZERO_LOG(LOG_ERR, "Session authentication failed for %s (code:%d)", ip_str, ret);
    }

    end:
    crules_free(&rules);
    if (request_attrs) rc_avpair_free(request_attrs);
    if (response_attrs) rc_avpair_free(response_attrs);

    return ret;
}
コード例 #22
0
ファイル: rad.c プロジェクト: KISSMonX/opensips
/*
	Radius implementation for the send_message callback
 */
int rad_send_message(aaa_conn* rh, aaa_message* request, aaa_message** reply) {
	char msg[4096];
	VALUE_PAIR *vp;
 	DICT_ATTR *attr;
	int result;

	if (!rh) {
		LM_ERR("invalid aaa connection argument\n");
		return -1;
	}

	if (!request) {
		LM_ERR("invalid argument\n");
		return -1;
	}

	if (request->type == AAA_AUTH) {

		*reply = (aaa_message*) pkg_malloc (sizeof(aaa_message));

		if (!(*reply)) {
			LM_ERR("no pkg memory left \n");
			return -1;
		}

		(*reply)->type = AAA_RECV;
		(*reply)->avpair = NULL;
		(*reply)->last_found = NULL;

		result = rc_auth(rh, SIP_PORT, (VALUE_PAIR*) request->avpair,
						(VALUE_PAIR**)(void*)&(*reply)->avpair, msg);

		if (result == OK_RC) {
			attr = rc_dict_findattr(rh, "SIP-AVP");
			if (attr) {
				vp = (*reply)->avpair;
				for(; (vp = rc_avpair_get(vp, attr->value, 0)); vp = vp->next)
					if (extract_avp(vp)) {
						LM_ERR("extract_avp failed\n");
						return -1;
					}
				return 0;
			} else {
				LM_ERR("SIP-AVP was not found in the radius dictionary\n");
				return -1;
			}
		} else if (result == REJECT_RC) {
			LM_DBG("rc_auth function succeded with result REJECT_RC\n");
			return result;
		} else {
			LM_ERR("rc_auth function failed\n");
			return -1;
		}
	}

	if (request->type == AAA_ACCT) {
			return rc_acct(rh, SIP_PORT, (VALUE_PAIR*) request->avpair);
	}

	LM_ERR("send message failure\n");
	return -1;
}
コード例 #23
0
ファイル: aaa_radius.c プロジェクト: ataillefer/opensips
int send_auth_func(struct sip_msg* msg, str* s1, str* s2) {

	int i, res;
	int index1 = -1, index2 = -1;
	map_list *mp;
	pv_value_t pvt;
	char mess[1024];

	VALUE_PAIR *send = NULL, *recv = NULL, *vp = NULL;

	if (!rh) {
		if (init_radius_handle()) {
			LM_ERR("invalid radius handle\n");
			return -1;
		}
	}

	for (i = 0; i < set_size; i++) {
		if (sets[i]->set_name.len == s1->len &&
				!strncmp(sets[i]->set_name.s, s1->s, s1->len))
				index1 = i;
		if (sets[i]->set_name.len == s2->len &&
				!strncmp(sets[i]->set_name.s, s2->s, s2->len))
				index2 = i;
	}

	if (index1 == -1) {
		LM_ERR("the first set was not found\n");
		return -1;
	}

	if (index2 == -1) {
		LM_ERR("the second set was not found\n");
		return -1;
	}

	if (make_send_message(msg, index1, &send) < 0) {
		LM_ERR("make message failed\n");
		return -1;
	}

	res = rc_auth(rh, SIP_PORT, send, &recv, mess);
	if (res!=OK_RC && res!=BADRESP_RC) {
		LM_ERR("radius authentication message failed with %s\n",
			(res==TIMEOUT_RC)?"TIMEOUT":"ERROR");
	}else{
		LM_DBG("radius authentication message sent\n");
	}

	for ( mp=sets[index2]->parsed; mp ; mp = mp->next) {
		vp = recv;
		while ( (vp=rc_avpair_get(vp, ATTRID(mp->value), VENDOR(mp->value)))!=NULL ) {
			memset(&pvt, 0, sizeof(pv_value_t));
			if (vp->type == PW_TYPE_INTEGER) {
				pvt.flags = PV_VAL_INT|PV_TYPE_INT;
				pvt.ri = vp->lvalue;
			}
			else
			if (vp->type == PW_TYPE_STRING) {
				pvt.flags = PV_VAL_STR;
				pvt.rs.s = vp->strvalue;
				pvt.rs.len = vp->lvalue;
			}
			if (pv_set_value(msg, mp->pv, (int)EQ_T, &pvt) < 0) {
				LM_ERR("setting avp failed....skipping\n");
			}
			vp = fetch_all_values ? vp->next : NULL;
		}
	}

	vp = recv;
	if (attr)
		for(; (vp = rc_avpair_get(vp, attr->value, 0)); vp = vp->next)
			extract_avp(vp);

	if ( res!=OK_RC && res!=BADRESP_RC)
		goto error;


	if (send) rc_avpair_free(send);
	if (recv) rc_avpair_free(recv);

	return (res==OK_RC)?1:-2;
error:
	if (send) rc_avpair_free(send);
	if (recv) rc_avpair_free(recv);
	return -1;
}
コード例 #24
0
ファイル: mod_xml_radius.c プロジェクト: PauloFer1/FreeSWITCH
switch_xml_t mod_xml_radius_auth_reg(switch_event_t *params) {
	int result = 0, param_idx = 0;
	VALUE_PAIR *send = NULL, *recv = NULL, *service_vp = NULL;
	char msg[512 * 10 + 1] = {0};
	uint32_t service = PW_AUTHENTICATE_ONLY;
	rc_handle *new_handle = NULL;
	switch_xml_t fields, xml, dir, dom, usr, vars, var;
	char name[512], value[512], *strtmp;

	if (GLOBAL_DEBUG ) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: starting registration authentication\n");
	}
	
	if ( mod_xml_radius_new_handle(&new_handle, globals.auth_invite_configs) != SWITCH_STATUS_SUCCESS ) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to load radius handle for registration authentication\n");
		goto err;		
	}

	if ( new_handle == NULL ) {
		goto err;
	}
	
	if ((fields = switch_xml_child(globals.auth_reg_configs, "fields")) == NULL ) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not find 'fields' section in config file.\n");		
		goto err;
	}
	
	if ( mod_xml_radius_add_params(NULL, params, new_handle, &send, fields) != SWITCH_STATUS_SUCCESS ) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to add params to rc_handle\n");		
		goto err;
	}
	
	if (rc_avpair_add(new_handle, &send, PW_SERVICE_TYPE, &service, -1, 0) == NULL) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: failed to add option to handle\n");
		goto err;
	}
	
	result = rc_auth(new_handle, 0, send, &recv, msg);
	
	if ( GLOBAL_DEBUG ){
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: result(RC=%d) %s \n", result, msg);
	}
	
	if ( result != 0 ) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: Failed to authenticate\n");
		goto err;
	}

	xml = switch_xml_new("document");
	switch_xml_set_attr_d(xml, "type", "freeswitch/xml");
	dir = switch_xml_add_child_d(xml, "section", 0);
	switch_xml_set_attr_d(dir, "name", "directory");
	dom = switch_xml_add_child_d(dir, "domain", 0);
	switch_xml_set_attr_d(dom, "name", switch_event_get_header(params, "domain"));
	usr = switch_xml_add_child_d(dom, "user", 0);
	vars = switch_xml_add_child_d(usr, "variables", 0);
	
	switch_xml_set_attr_d(usr, "id", switch_event_get_header(params, "user"));
		
	service_vp = recv;
	while (service_vp != NULL) {
		rc_avpair_tostr(new_handle, service_vp, name, 512, value, 512);
		if ( GLOBAL_DEBUG )
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "\tattribute (%s)[%s] found in radius packet\n", name, value);
		var = switch_xml_add_child_d(vars, "variable", param_idx++);
		strtmp = strdup(name);
		switch_xml_set_attr_d(var, "name", strtmp);
		free(strtmp);
		strtmp = strdup(value);
		switch_xml_set_attr_d(var, "value", strtmp);
		free(strtmp);
		service_vp = service_vp->next;
	}

	if ( GLOBAL_DEBUG ) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "XML: %s \n", switch_xml_toxml(xml, 1));
	}
	
	if ( recv ) {
		rc_avpair_free(recv);
		recv = NULL;
	}
	if ( send ) {
		rc_avpair_free(send);
		send = NULL;
	}
	if ( new_handle ) {
		rc_destroy(new_handle);
		new_handle = NULL;
	}

	return xml;
 err:
	if ( recv ) {
		rc_avpair_free(recv);
		recv = NULL;
	}
	if ( send ) {
		rc_avpair_free(send);
		send = NULL;
	}
	if ( new_handle ) {
		rc_destroy(new_handle);
		new_handle = NULL;
	}
	
	return NULL;
}