Esempio n. 1
0
/*! \brief
 * Extract Address of Record
 */
int extract_aor(str* _uri, str* _a)
{
	static char aor_buf[MAX_AOR_LEN];
	memset(aor_buf, 0, MAX_AOR_LEN);

	str tmp;
	struct sip_uri puri;
	int user_len;

	if (parse_uri(_uri->s, _uri->len, &puri) < 0) {
		rerrno = R_AOR_PARSE;
		LM_ERR("failed to parse Address of Record\n");
		return -1;
	}
	
	if ( (puri.user.len + puri.host.len + 1) > MAX_AOR_LEN
	|| puri.user.len > USERNAME_MAX_SIZE
	||  puri.host.len > DOMAIN_MAX_SIZE ) {
		rerrno = R_AOR_LEN;
		LM_ERR("Address Of Record too long\n");
		return -2;
	}

	_a->s = aor_buf;
	_a->len = puri.user.len;

	if (un_escape(&puri.user, _a) < 0) {
		rerrno = R_UNESCAPE;
		LM_ERR("failed to unescape username\n");
		return -3;
	}

	user_len = _a->len;

	if (reg_use_domain) {
		if (user_len)
			aor_buf[_a->len++] = '@';
		/* strip prefix (if defined) */
		if (realm_prefix.len && realm_prefix.len<puri.host.len &&
		(memcmp(realm_prefix.s, puri.host.s, realm_prefix.len)==0) ) {
			memcpy(aor_buf + _a->len, puri.host.s + realm_prefix.len,
					puri.host.len - realm_prefix.len);
			_a->len += puri.host.len - realm_prefix.len;
		} else {
			memcpy(aor_buf + _a->len, puri.host.s, puri.host.len);
			_a->len += puri.host.len;
		}
	}

	if (case_sensitive && user_len) {
		tmp.s = _a->s + user_len + 1;
		tmp.len = _a->s + _a->len - tmp.s;
		strlower(&tmp);
	} else {
		strlower(_a);
	}

	return 0;
}
Esempio n. 2
0
/*
 * Extract Address of Record
 */
int extract_aor(str* _uri, str* _a)
{
	static char aor_buf[MAX_AOR_LEN];
	str tmp;
	struct sip_uri puri;
	int user_len;

	if (parse_uri(_uri->s, _uri->len, &puri) < 0) {
		rerrno = R_AOR_PARSE;
		LOG(L_ERR, "extract_aor(): Error while parsing Address of Record\n");
		return -1;
	}
	
	if ((puri.user.len + puri.host.len + 1) > MAX_AOR_LEN) {
		rerrno = R_AOR_LEN;
		LOG(L_ERR, "extract_aor(): Address Of Record too long\n");
		return -2;
	}

	_a->s = aor_buf;
	_a->len = puri.user.len;

	if (un_escape(&puri.user, _a) < 0) {
		rerrno = R_UNESCAPE;
		LOG(L_ERR, "extract_aor(): Error while unescaping username\n");
		return -3;
	}

	user_len = _a->len;

	if (use_domain) {
		if (user_len)
			aor_buf[_a->len++] = '@';
		/* strip prefix (if defined) */
		if (realm_prefix.len && realm_prefix.len<puri.host.len &&
		(memcmp(realm_prefix.s, puri.host.s, realm_prefix.len)==0) ) {
			memcpy(aor_buf + _a->len, puri.host.s + realm_prefix.len,
					puri.host.len - realm_prefix.len);
			_a->len += puri.host.len - realm_prefix.len;
		} else {
			memcpy(aor_buf + _a->len, puri.host.s, puri.host.len);
			_a->len += puri.host.len;
		}
	}

	if (case_sensitive && user_len) {
		tmp.s = _a->s + user_len + 1;
		tmp.len = _a->s + _a->len - tmp.s;
		strlower(&tmp);
	} else {
		strlower(_a);
	}

	return 0;
}
Esempio n. 3
0
/*
 * Authorize digest credentials
 */
static inline int authorize(struct sip_msg* _msg, pv_elem_t* _realm,
			    pv_spec_t * _uri_user, int _hftype)
{
    int res;
    auth_result_t ret;
    struct hdr_field* h;
    auth_body_t* cred;
    str *uri_user;
    str user, domain;
    pv_value_t pv_val;

    /* get pre_auth domain from _realm pvar (if exists) */
    if (_realm) {
	if (pv_printf_s(_msg, _realm, &domain)!=0) {
	    LM_ERR("pv_printf_s failed\n");
	    return AUTH_ERROR;
	}
    } else {
	/* get pre_auth domain from To/From header */
	domain.len = 0;
	domain.s = 0;
    }

    ret = auth_api.pre_auth(_msg, &domain, _hftype, &h);

    if (ret != DO_AUTHORIZATION)
	return ret;

    cred = (auth_body_t*)h->parsed;

    /* get uri_user from _uri_user pvap (if exists) or
       from To/From URI */
    if (_uri_user) {
	if (pv_get_spec_value(_msg, _uri_user, &pv_val) == 0) {
	    if (pv_val.flags & PV_VAL_STR) {
		res = aaa_authorize_sterman(_msg, &cred->digest,
					       &_msg->first_line.u.request.method,
					       &pv_val.rs);
	    } else {
		LM_ERR("uri_user pvar value is not string\n");
		return AUTH_ERROR;
	    }
	} else {
	    LM_ERR("cannot get uri_user pvar value\n");
	    return AUTH_ERROR;
	}
    } else {
	if (get_uri_user(_msg, &uri_user) < 0) {
	    LM_ERR("To/From URI not found\n");
	    return AUTH_ERROR;
	}
	user.s = (char *)pkg_malloc(uri_user->len);
	if (user.s == NULL) {
	    LM_ERR("no pkg memory left for user\n");
	    return AUTH_ERROR;
	}
	un_escape(uri_user, &user);
	res = aaa_authorize_sterman(_msg, &cred->digest,
				       &_msg->first_line.u.request.method,
				       &user);
	pkg_free(user.s);
    }

    if (res == 1) {
	ret = auth_api.post_auth(_msg, h);
	return ret;
    }

    return AUTH_ERROR;
}
Esempio n. 4
0
/*! \brief
 * Extract Address of Record
 */
int extract_aor(str* _uri, str* _a) {
    static char aor_buf[MAX_AOR_LEN];
    str tmp;
    struct sip_uri puri;
    int user_len;
    int_str avp_val;
    struct usr_avp *avp;
    str *uri;
    str realm_prefix;

    memset(aor_buf, 0, MAX_AOR_LEN);
    if (aor_avp_name.n != 0) {
        avp = search_first_avp(aor_avp_type, aor_avp_name, &avp_val, 0);
        if (avp && is_avp_str_val(avp)) {
            uri = &avp_val.s;
        } else {
            uri = _uri;
        }
    } else {
        uri = _uri;
    }

    if (parse_uri(uri->s, uri->len, &puri) < 0) {
        rerrno = R_AOR_PARSE;
        LM_ERR("failed to parse Address of Record\n");
        return -1;
    }

    if ((puri.user.len + puri.host.len + 1 + 4) > MAX_AOR_LEN
            || puri.user.len > USERNAME_MAX_SIZE
            || puri.host.len > DOMAIN_MAX_SIZE) {
        rerrno = R_AOR_LEN;
        LM_ERR("Address Of Record too long\n");
        return -2;
    }

    _a->s = aor_buf;
    _a->len = puri.user.len + 4;
    strncpy(_a->s, "sip:", 4);

    str tmps;
    tmps.s = _a->s + 4;
    tmps.len = puri.user.len;

    if (un_escape(&puri.user, &tmps) < 0) {
        rerrno = R_UNESCAPE;
        LM_ERR("failed to unescape username\n");
        return -3;
    }

    user_len = tmps.len + 4;//_a->len;

    if (user_len>4)
        aor_buf[_a->len++] = '@';
    /* strip prefix (if defined) */
    realm_prefix.s = cfg_get(registrar, registrar_cfg, realm_pref);
    realm_prefix.len = strlen(realm_prefix.s);
    if (realm_prefix.len && realm_prefix.len < puri.host.len
            && (memcmp(realm_prefix.s, puri.host.s, realm_prefix.len) == 0)) {
        memcpy(aor_buf + _a->len, puri.host.s + realm_prefix.len,
               puri.host.len - realm_prefix.len);
        _a->len += puri.host.len - realm_prefix.len;
    } else {
        memcpy(aor_buf + _a->len, puri.host.s, puri.host.len);
        _a->len += puri.host.len;
    }

    if (cfg_get(registrar, registrar_cfg, case_sensitive) && user_len) {
        tmp.s = _a->s + user_len + 1;
        tmp.len = _a->s + _a->len - tmp.s;
        strlower(&tmp);
    } else {
        strlower(_a);
    }

    return 0;
}
Esempio n. 5
0
/*
 * Authorize digest credentials
 */
static inline int authorize(struct sip_msg* _msg, pv_elem_t* _realm,
			    pv_spec_t * _uri_user, hdr_types_t _hftype)
{
    int res;
    auth_cfg_result_t ret;
    struct hdr_field* h;
    auth_body_t* cred;
    str *uri_user;
    str user, domain;
    pv_value_t pv_val;

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

    /* get pre_auth domain from _realm pvar (if exists) */
    if (_realm) {
	if (pv_printf_s(_msg, _realm, &domain) != 0) {
	    LM_ERR("pv_printf_s failed\n");
	    return -5;
	}
    } else {
	domain.len = 0;
	domain.s = 0;
    }

    switch(auth_api.pre_auth(_msg, &domain, _hftype, &h, NULL)) {
    default:
	BUG("unexpected reply '%d'.\n",
	    auth_api.pre_auth(_msg, &domain, _hftype, &h, NULL));
#ifdef EXTRA_DEBUG
	abort();
#endif
	ret = -7;
	goto end;

    case NONCE_REUSED:
	ret = AUTH_NONCE_REUSED;
	goto end;

    case STALE_NONCE:
	ret = AUTH_STALE_NONCE;
	goto end;
	
    case ERROR:
    case BAD_CREDENTIALS:
    case NOT_AUTHENTICATED:
	ret = AUTH_ERROR;
	goto end;

    case NO_CREDENTIALS:
	ret = AUTH_NO_CREDENTIALS;
	goto end;
	
    case DO_AUTHENTICATION:
	break;
	
    case AUTHENTICATED:
	ret = AUTH_OK;
	goto end;
    }

    cred = (auth_body_t*)h->parsed;

    /* get uri_user from _uri_user pvap (if exists) or
       from To/From URI */
    if (_uri_user) {
	if (pv_get_spec_value(_msg, _uri_user, &pv_val) == 0) {
	    if (pv_val.flags & PV_VAL_STR) {
		res = radius_authorize_sterman(_msg, &cred->digest, 
					       &_msg->
					       first_line.u.request.method,
					       &pv_val.rs);
	    } else {
		LM_ERR("uri_user pvar value is not string\n");
		ret = AUTH_ERROR;
		goto end;
	    }
	} else {
	    LM_ERR("cannot get uri_user pvar value\n");
	    ret = AUTH_ERROR;
	    goto end;
	}
    } else {
	if (get_uri_user(_msg, &uri_user) < 0) {
	    LM_ERR("To/From URI not found\n");
	    ret = AUTH_ERROR;;
	    goto end;
	}
	user.s = (char *)pkg_malloc(uri_user->len);
	if (user.s == NULL) {
	    LM_ERR("no pkg memory left for user\n");
	    ret = -7;
	    goto end;
	}
	un_escape(uri_user, &user);
	res = radius_authorize_sterman(_msg, &cred->digest, 
				       &_msg->first_line.u.request.method,
				       &user);
    }

    if (res == 1) {
	switch(auth_api.post_auth(_msg, h, NULL)) {
	default:
	    BUG("unexpected reply '%d'.\n",
		auth_api.pre_auth(_msg, &domain, _hftype, &h, NULL));
#ifdef EXTRA_DEBUG
	    abort();
#endif
	    ret = -7;
	    break;
	case ERROR:             
	case NOT_AUTHENTICATED:
	    ret = AUTH_ERROR;
	    break;
	case AUTHENTICATED:
	    ret = AUTH_OK;
	    break;
	}
    } else {
	ret = AUTH_INVALID_PASSWORD;
    }

 end:
    if (user.s) pkg_free(user.s);
    if (ret < 0) {
	if (auth_api.build_challenge(_msg, (cred ? cred->stale : 0), &domain,
				     NULL, NULL, _hftype) < 0) {
	    LM_ERR("while creating challenge\n");
	    ret = -7;
	}
    }
    return ret;
}
Esempio n. 6
0
/*! \brief
 * Extract Address of Record
 * In case of public GRUUs, also populates sip_instance
 * In case of temp GRUUs, also populates call_id
 */
int extract_aor(str* _uri, str* _a,str *sip_instance,str *call_id)
{
	static char aor_buf[MAX_AOR_LEN];
	memset(aor_buf, 0, MAX_AOR_LEN);

	str tmp;
	struct sip_uri puri;
	int user_len,tgruu_len,dec_size,i;
	str *magic;

	if (parse_uri(_uri->s, _uri->len, &puri) < 0) {
		rerrno = R_AOR_PARSE;
		LM_ERR("failed to parse Address of Record\n");
		return -1;
	}

	/* if have ;gr param and func caller is interested in 
	 * potentially extracting the sip instance */
	if ((puri.gr.s && puri.gr.len) && sip_instance)
	{
		LM_DBG("has gruu\n");

		/* ;gr param detected */
		if (memcmp(puri.user.s,TEMP_GRUU,TEMP_GRUU_SIZE) == 0)
		{
			LM_DBG("temp gruu\n");
			/* temp GRUU, decode and extract aor, sip_instance
			 * and call_id */
			tgruu_len = puri.user.len - TEMP_GRUU_SIZE;
			memcpy(tgruu_dec,puri.user.s+TEMP_GRUU_SIZE,tgruu_len);

			if (gruu_secret.s != NULL)
				magic = &gruu_secret;
			else
				magic = &default_gruu_secret;

			dec_size = base64decode((unsigned char *)tgruu_dec,
					(unsigned char *)tgruu_dec,tgruu_len);

			for (i=0;i<tgruu_len;i++)
				tgruu_dec[i] ^= magic->s[i%magic->len];

			LM_DBG("decoded [%.*s]\n",dec_size,tgruu_dec);
			/* extract aor - skip tgruu generation time at 
			 * the beggining */
			_a->s = (char *)memchr(tgruu_dec,' ',dec_size) + 1;
			if (_a->s == NULL) {
				rerrno = R_AOR_PARSE;
				LM_ERR("failed to parse Address of Record\n");
				return -1;
			}
			_a->len = (char *)memchr(_a->s,' ',dec_size - (_a->s-tgruu_dec)) - _a->s;
			if (_a->len < 0) { 
				rerrno = R_AOR_PARSE;
				LM_ERR("failed to parse Address of Record\n");
				return -1;
			}

			sip_instance->s = _a->s+_a->len+1; /* skip ' ' */
			if (sip_instance->s >= tgruu_dec + dec_size) {
				rerrno = R_AOR_PARSE;
				LM_ERR("failed to parse Address of Record\n");
				return -1;
			}
			sip_instance->len = (char *)memchr(sip_instance->s,' ',
					dec_size-(sip_instance->s-tgruu_dec)) - sip_instance->s;
			if (sip_instance->len < 0) { 
				rerrno = R_AOR_PARSE;
				LM_ERR("failed to parse Address of Record\n");
				return -1;
			}

			call_id->s = sip_instance->s + sip_instance->len + 1;
			if (call_id->s >= tgruu_dec + dec_size) {
				rerrno = R_AOR_PARSE;
				LM_ERR("failed to parse Address of Record\n");
				return -1;
			}
			call_id->len = (tgruu_dec+dec_size) - call_id->s;

			LM_DBG("extracted aor [%.*s] and instance [%.*s] and callid [%.*s]\n",_a->len,_a->s,
					sip_instance->len,sip_instance->s,call_id->len,call_id->s);

			/* skip checks - done at save() */
			return 0;
		}
		else
		{
			LM_DBG("public gruu\n");
			*sip_instance = puri.gr_val;
		}
	}
	
	if ( (puri.user.len + puri.host.len + 1) > MAX_AOR_LEN
	|| puri.user.len > USERNAME_MAX_SIZE
	||  puri.host.len > DOMAIN_MAX_SIZE ) {
		rerrno = R_AOR_LEN;
		LM_ERR("Address Of Record too long\n");
		return -2;
	}

	_a->s = aor_buf;
	_a->len = puri.user.len;

	if (un_escape(&puri.user, _a) < 0) {
		rerrno = R_UNESCAPE;
		LM_ERR("failed to unescape username\n");
		return -3;
	}

	user_len = _a->len;

	if (reg_use_domain) {
		if (user_len)
			aor_buf[_a->len++] = '@';
		/* strip prefix (if defined) */
		if (realm_prefix.len && realm_prefix.len<puri.host.len &&
		(memcmp(realm_prefix.s, puri.host.s, realm_prefix.len)==0) ) {
			memcpy(aor_buf + _a->len, puri.host.s + realm_prefix.len,
					puri.host.len - realm_prefix.len);
			_a->len += puri.host.len - realm_prefix.len;
		} else {
			memcpy(aor_buf + _a->len, puri.host.s, puri.host.len);
			_a->len += puri.host.len;
		}
	}

	if (case_sensitive && user_len) {
		tmp.s = _a->s + user_len + 1;
		tmp.len = _a->s + _a->len - tmp.s;
		strlower(&tmp);
	} else {
		strlower(_a);
	}

	return 0;
}
Esempio n. 7
0
/*
 * Authorize digest credentials
 */
static inline int authorize(struct sip_msg* _msg, str* _realm, int _hftype)
{
	int res;
	auth_result_t ret;
	struct hdr_field* h;
	auth_body_t* cred;
	str* uri;
	struct sip_uri puri;
	str user, domain;

	domain = *_realm;
	ret = pre_auth_func(_msg, &domain, _hftype, &h);
	
	switch(ret) {
	case ERROR:            return 0;
	case NOT_AUTHORIZED:   return -1;
	case DO_AUTHORIZATION: break;
	case AUTHORIZED:       return 1;
	}

	cred = (auth_body_t*)h->parsed;

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

	if (puri.host.len != cred->digest.realm.len) {
		DBG("authorize(): Credentials realm and URI host do not match\n");   
		return -1;
	}
	if (strncasecmp(puri.host.s, cred->digest.realm.s, puri.host.len) != 0) {
		DBG("authorize(): Credentials realm and URI host do not match\n");
		return -1;
	}

	user.s = (char *)pkg_malloc(puri.user.len);
	un_escape(&(puri.user), &user);

	     /* Clear the rpid buffer from previous value */
	rpid.len = 0;

	res = radius_authorize_sterman(_msg, &cred->digest, &_msg->first_line.u.request.method, &user, &rpid);
	pkg_free(user.s);

	if (res == 1) {
		ret = post_auth_func(_msg, h, &rpid);
		switch(ret) {
		case ERROR:          return 0;
		case NOT_AUTHORIZED: return -1;
		case AUTHORIZED:     return 1;
		default:             return -1;
		}
	}

	return -1;
}
Esempio n. 8
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;
}
/***********************************************************************
 * @todo Maybe invoice checking should be done in gnc_bi_import_fix_bis (...)
 * rather than in here?  But that is more concerned with ensuring the csv is consistent.
 * @param GtkListStore *store
 * @param guint *n_invoices_created
 * @param guint *n_invoices_updated
 * @return void
 ***********************************************************************/
void
gnc_bi_import_create_bis (GtkListStore * store, QofBook * book,
                          guint * n_invoices_created,
                          guint * n_invoices_updated,
                          gchar * type, gchar * open_mode, GString * info)
{
    gboolean valid;
    GtkTreeIter iter;
    gchar *id = NULL, *date_opened = NULL, *owner_id = NULL, *billing_id = NULL, *notes = NULL;
    gchar *date = NULL, *desc = NULL, *action = NULL, *account = NULL, *quantity = NULL,
          *price = NULL, *disc_type = NULL, *disc_how = NULL, *discount = NULL, *taxable = NULL,
          *taxincluded = NULL, *tax_table = NULL;
    gchar *date_posted = NULL, *due_date = NULL, *account_posted = NULL, *memo_posted = NULL,
          *accumulatesplits = NULL;
    guint dummy;
    GncInvoice *invoice;
    GncEntry *entry;
    gint day, month, year;
    gnc_numeric value;
    GncOwner *owner;
    Account *acc;
    enum update {YES = GTK_RESPONSE_YES, NO = GTK_RESPONSE_NO} update;
    GtkWidget *dialog;
    Timespec today;
    InvoiceWindow *iw;
    gchar *new_id = NULL;
    gint64 denom = 0;
    gnc_commodity *currency;

    // these arguments are needed
    g_return_if_fail (store && book);
    // logic of this function only works for bills or invoices
    g_return_if_fail ((g_ascii_strcasecmp (type, "INVOICE") == 0) ||
            (g_ascii_strcasecmp (type, "BILL") == 0));

    // allow to call this function without statistics
    if (!n_invoices_created)
        n_invoices_created = &dummy;
    if (!n_invoices_updated)
        n_invoices_updated = &dummy;
    *n_invoices_created = 0;
    *n_invoices_updated = 0;

    invoice = NULL;
    update = NO;

    valid = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter);
    while (valid)
    {
        // Walk through the list, reading each row
        gtk_tree_model_get (GTK_TREE_MODEL (store), &iter,
                            ID, &id,
                            DATE_OPENED, &date_opened,
                            DATE_POSTED, &date_posted,       // if autoposting requested
                            DUE_DATE, &due_date,             // if autoposting requested
                            ACCOUNT_POSTED, &account_posted, // if autoposting requested
                            MEMO_POSTED, &memo_posted,       // if autoposting requested
                            ACCU_SPLITS, &accumulatesplits,  // if autoposting requested
                            OWNER_ID, &owner_id,
                            BILLING_ID, &billing_id,
                            NOTES, &notes,
                            DATE, &date,
                            DESC, &desc,
                            ACTION, &action,
                            ACCOUNT, &account,
                            QUANTITY, &quantity,
                            PRICE, &price,
                            DISC_TYPE, &disc_type,
                            DISC_HOW, &disc_how,
                            DISCOUNT, &discount,
                            TAXABLE, &taxable,
                            TAXINCLUDED, &taxincluded,
                            TAX_TABLE, &tax_table, -1);

        // TODO:  Assign a new invoice number if one is absent.  BUT we don't want to assign a new invoice for every line!!
        // so we'd have to flag this up somehow or add an option in the import GUI.  The former implies that we make
        // an assumption about what the importer (person) wants to do.  It seems reasonable that a CSV file full of items with
        // If an invoice exists then we add to it in this current schema.
        // no predefined invoice number is a new invoice that's in need of a new number.
        // This was  not designed to satisfy the need for repeat invoices however, so maybe we need a another method for this, after all
        // It should be easier to copy an invoice with a new ID than to go through all this malarky.
        if (g_ascii_strcasecmp (type, "BILL") == 0)
            invoice = gnc_search_bill_on_id (book, id);
        else if (g_ascii_strcasecmp (type, "INVOICE") == 0)
            invoice = gnc_search_invoice_on_id (book, id);
        DEBUG( "Existing %s ID: %s\n", type, gncInvoiceGetID(invoice));

        // If the search is empty then there is no existing invoice so make a new one
        if (invoice == NULL)
        {
             DEBUG( "Creating a new : %s\n", type );
            // new invoice
            invoice = gncInvoiceCreate (book);
            /* Protect against thrashing the DB and trying to write the invoice
             * record prematurely */
            gncInvoiceBeginEdit (invoice);
            gncInvoiceSetID (invoice, id);
            owner = gncOwnerNew ();
            if (g_ascii_strcasecmp (type, "BILL") == 0)
                gncOwnerInitVendor (owner,
                                    gnc_search_vendor_on_id (book, owner_id));
            else if (g_ascii_strcasecmp (type, "INVOICE") == 0)
                gncOwnerInitCustomer (owner,
                                      gnc_search_customer_on_id (book, owner_id));
            gncInvoiceSetOwner (invoice, owner);
            gncInvoiceSetCurrency (invoice, gncOwnerGetCurrency (owner));	// Set the invoice currency based on the owner
            if (strlen (date_opened) != 0)	// If a date is specified in CSV
            {
                // FIXME: Must check for the return value of qof_scan_date!
                qof_scan_date (date_opened, &day, &month, &year);
                gncInvoiceSetDateOpened (invoice,
                                         gnc_dmy2timespec (day, month, year));
            }
            else			// If no date in CSV
            {
                time64 now = gnc_time (NULL);
                Timespec now_timespec;
                timespecFromTime64 (&now_timespec, now);
                gncInvoiceSetDateOpened (invoice, now_timespec);
            }
            gncInvoiceSetBillingID (invoice, billing_id ? billing_id : "");
            notes = un_escape(notes);
            gncInvoiceSetNotes (invoice, notes ? notes : "");
            gncInvoiceSetActive (invoice, TRUE);
            //if (g_ascii_strcasecmp(type,"INVOICE"))gncInvoiceSetBillTo( invoice, billto );
            (*n_invoices_created)++;
            update = YES;

            // open new bill / invoice in a tab, if requested
            if (g_ascii_strcasecmp(open_mode, "ALL") == 0
                    || (g_ascii_strcasecmp(open_mode, "NOT_POSTED") == 0
                        && strlen(date_posted) == 0))
            {
                iw =  gnc_ui_invoice_edit (invoice);
                gnc_plugin_page_invoice_new (iw);
            }
            gncInvoiceCommitEdit (invoice);
        }
// I want to warn the user that an existing billvoice exists, but not every
// time.
// An import can contain many lines usually referring to the same invoice.
// NB: Posted invoices are NEVER updated.
        else			// if invoice exists
        {
            if (gncInvoiceIsPosted (invoice))	// Is it already posted?
            {
                valid =
                    gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter);
                continue;		// If already posted then never import
            }
            if (update != YES)	// Pop up a dialog to ask if updates are the expected action
            {
                dialog = gtk_message_dialog_new (NULL,
                                                 GTK_DIALOG_MODAL,
                                                 GTK_MESSAGE_ERROR,
                                                 GTK_BUTTONS_YES_NO,
                                                 "%s",
                                                 _("Are you sure you have bills/invoices to update?"));
                update = gtk_dialog_run (GTK_DIALOG (dialog));
                gtk_widget_destroy (dialog);
                if (update == NO)
                {
                    // Cleanup and leave
                    g_free (id);
                    g_free (date_opened);
                    g_free (owner_id);
                    g_free (billing_id);
                    g_free (notes);
                    g_free (date);
                    g_free (desc);
                    g_free (action);
                    g_free (account);
                    g_free (quantity);
                    g_free (price);
                    g_free (disc_type);
                    g_free (disc_how);
                    g_free (discount);
                    g_free (taxable);
                    g_free (taxincluded);
                    g_free (tax_table);
                    g_free (date_posted);
                    g_free (due_date);
                    g_free (account_posted);
                    g_free (memo_posted);
                    g_free (accumulatesplits);
                    return;
                }
            }
            (*n_invoices_updated)++;
        }


        // add entry to invoice/bill
        entry = gncEntryCreate (book);
        gncEntryBeginEdit(entry);
        currency = gncInvoiceGetCurrency(invoice);
        if (currency) denom = gnc_commodity_get_fraction(currency);
        // FIXME: Must check for the return value of qof_scan_date!
        qof_scan_date (date, &day, &month, &year);
        {
            GDate *date = g_date_new_dmy(day, month, year);
            gncEntrySetDateGDate (entry, date);
            g_date_free (date);
        }
        timespecFromTime64 (&today, gnc_time (NULL));	// set today to the current date
        gncEntrySetDateEntered (entry, today);
        // Remove escaped quotes
        desc = un_escape(desc);
        notes = un_escape(notes);
        gncEntrySetDescription (entry, desc);
        gncEntrySetAction (entry, action);
        value = gnc_numeric_zero(); 
        gnc_exp_parser_parse (quantity, &value, NULL);
        // Need to set the denom appropriately else we get stupid rounding errors.
        value = gnc_numeric_convert (value, denom * 100, GNC_HOW_RND_NEVER);
        //DEBUG("qty = %s",gnc_num_dbg_to_string(value));
        gncEntrySetQuantity (entry, value);
        acc = gnc_account_lookup_for_register (gnc_get_current_root_account (),
                                               account);

        if (g_ascii_strcasecmp (type, "BILL") == 0)
        {
            gncEntrySetBillAccount (entry, acc);
            value = gnc_numeric_zero();
            gnc_exp_parser_parse (price, &value, NULL);
            value = gnc_numeric_convert (value, denom * 100, GNC_HOW_RND_NEVER);
            gncEntrySetBillPrice (entry, value);
            gncEntrySetBillTaxable (entry, text2bool (taxable));
            gncEntrySetBillTaxIncluded (entry, text2bool (taxincluded));
            gncEntrySetBillTaxTable (entry, gncTaxTableLookupByName (book, tax_table));
            gncEntryCommitEdit(entry);
            gncBillAddEntry (invoice, entry);
        }
        else if (g_ascii_strcasecmp (type, "INVOICE") == 0)
        {
            gncEntrySetNotes (entry, notes);
            gncEntrySetInvAccount (entry, acc);
            value = gnc_numeric_zero();
            gnc_exp_parser_parse (price, &value, NULL);
            value = gnc_numeric_convert (value, denom * 100, GNC_HOW_RND_NEVER);
            //DEBUG("price = %s",gnc_num_dbg_to_string(value));
            gncEntrySetInvPrice (entry, value);
            gncEntrySetInvTaxable (entry, text2bool (taxable));
            gncEntrySetInvTaxIncluded (entry, text2bool (taxincluded));
            gncEntrySetInvTaxTable (entry, gncTaxTableLookupByName (book, tax_table));
            value = gnc_numeric_zero();
            gnc_exp_parser_parse (discount, &value, NULL);
            value = gnc_numeric_convert (value, denom * 100, GNC_HOW_RND_NEVER);
            gncEntrySetInvDiscount (entry, value);
            gncEntrySetInvDiscountType (entry, text2disc_type (disc_type));
            gncEntrySetInvDiscountHow (entry, text2disc_how (disc_how));
            gncEntryCommitEdit(entry);
            gncInvoiceAddEntry (invoice, entry);
        }
        valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter);
        // handle auto posting of invoices

        new_id = NULL;
       
        if (valid)
            gtk_tree_model_get (GTK_TREE_MODEL (store), &iter, ID, &new_id, -1);
        if (g_strcmp0 (id, new_id) != 0)
        {
            // the next invoice id is different => try to autopost this invoice
            if (qof_scan_date (date_posted, &day, &month, &year))
            {
                // autopost this invoice
                gboolean auto_pay;
                Timespec d1, d2;

                if (g_ascii_strcasecmp (type, "INVOICE") == 0)
                    auto_pay = gnc_prefs_get_bool (GNC_PREFS_GROUP_INVOICE, GNC_PREF_AUTO_PAY);
                else
                    auto_pay = gnc_prefs_get_bool (GNC_PREFS_GROUP_BILL, GNC_PREF_AUTO_PAY);

                d1 = gnc_dmy2timespec (day, month, year);
                // FIXME: Must check for the return value of qof_scan_date!
                qof_scan_date (due_date, &day, &month, &year);	// obtains the due date, or leaves it at date_posted
                d2 = gnc_dmy2timespec (day, month, year);
                acc = gnc_account_lookup_for_register
                      (gnc_get_current_root_account (), account_posted);
                gncInvoicePostToAccount (invoice, acc, &d1, &d2,
                                         memo_posted,
                                         text2bool (accumulatesplits),
                                         auto_pay);
                DEBUG("Invoice %s posted",id);
            }

        }


    }
    // cleanup
    g_free (new_id);
    g_free (id);
    g_free (date_opened);
    g_free (owner_id);
    g_free (billing_id);
    g_free (notes);
    g_free (date);
    g_free (desc);
    g_free (action);
    g_free (account);
    g_free (quantity);
    g_free (price);
    g_free (disc_type);
    g_free (disc_how);
    g_free (discount);
    g_free (taxable);
    g_free (taxincluded);
    g_free (tax_table);
    g_free (date_posted);
    g_free (due_date);
    g_free (account_posted);
    g_free (memo_posted);
    g_free (accumulatesplits);

}
Esempio n. 10
0
/*! \brief
 * Extract Address of Record
 */
int extract_aor(str* _uri, str* _a, sip_uri_t *_pu)
{
	static char aor_buf[MAX_AOR_LEN];
	str tmp;
	sip_uri_t turi;
	sip_uri_t *puri;
	int user_len;
	str *uri;
	str realm_prefix = {0};

	memset(aor_buf, 0, MAX_AOR_LEN);
	uri=_uri;

	if(_pu!=NULL)
		puri = _pu;
	else
		puri = &turi;

	if (parse_uri(uri->s, uri->len, puri) < 0) {
		rerrno = R_AOR_PARSE;
		LM_ERR("failed to parse AoR [%.*s]\n", uri->len, uri->s);
		return -1;
	}

	if ( (puri->user.len + puri->host.len + 1) > MAX_AOR_LEN
	|| puri->user.len > USERNAME_MAX_SIZE
	||  puri->host.len > DOMAIN_MAX_SIZE ) {
		rerrno = R_AOR_LEN;
		LM_ERR("Address Of Record too long\n");
		return -2;
	}

	_a->s = aor_buf;
	_a->len = puri->user.len;

	if (un_escape(&puri->user, _a) < 0) {
		rerrno = R_UNESCAPE;
		LM_ERR("failed to unescape username\n");
		return -3;
	}

	user_len = _a->len;

	if (reg_use_domain) {
		if (user_len)
			aor_buf[_a->len++] = '@';
		/* strip prefix (if defined) */
		realm_prefix.len = cfg_get(registrar, registrar_cfg, realm_pref).len;
		if(realm_prefix.len>0) {
			realm_prefix.s = cfg_get(registrar, registrar_cfg, realm_pref).s;
			LM_DBG("realm prefix is [%.*s]\n", realm_prefix.len,
					(realm_prefix.len>0)?realm_prefix.s:"");
		}
		if (realm_prefix.len>0
				&& realm_prefix.len<puri->host.len
				&& (memcmp(realm_prefix.s, puri->host.s, realm_prefix.len)==0))
		{
			memcpy(aor_buf + _a->len, puri->host.s + realm_prefix.len,
					puri->host.len - realm_prefix.len);
			_a->len += puri->host.len - realm_prefix.len;
		} else {
			memcpy(aor_buf + _a->len, puri->host.s, puri->host.len);
			_a->len += puri->host.len;
		}
	}

	if (cfg_get(registrar, registrar_cfg, case_sensitive) && user_len) {
		tmp.s = _a->s + user_len + 1;
		tmp.len = _a->s + _a->len - tmp.s;
		strlower(&tmp);
	} else {
		strlower(_a);
	}

	return 0;
}