Example #1
0
static inline int auth_get_ha1(struct sip_msg *msg, struct username* _username,
                               str* _domain, char* _ha1)
{
    pv_value_t sval;

    /* get username from PV */
    memset(&sval, 0, sizeof(pv_value_t));
    if(pv_get_spec_value(msg, &user_spec, &sval)==0)
    {
        if(sval.flags==PV_VAL_NONE || (sval.flags&PV_VAL_NULL)
                || (sval.flags&PV_VAL_EMPTY) || (!(sval.flags&PV_VAL_STR)))
        {
            pv_value_destroy(&sval);
            return 1;
        }
        if(sval.rs.len!= _username->whole.len
                || strncasecmp(sval.rs.s, _username->whole.s, sval.rs.len))
        {
            LM_DBG("username mismatch [%.*s] [%.*s]\n",
                   _username->whole.len, _username->whole.s, sval.rs.len, sval.rs.s);
            pv_value_destroy(&sval);
            return 1;
        }
    } else {
        return 1;
    }
    /* get password from PV */
    memset(&sval, 0, sizeof(pv_value_t));
    if(pv_get_spec_value(msg, &passwd_spec, &sval)==0)
    {
        if(sval.flags==PV_VAL_NONE || (sval.flags&PV_VAL_NULL)
                || (sval.flags&PV_VAL_EMPTY) || (!(sval.flags&PV_VAL_STR)))
        {
            pv_value_destroy(&sval);
            return 1;
        }
    } else {
        return 1;
    }
    if (auth_calc_ha1) {
        /* Only plaintext passwords are stored in database,
         * we have to calculate HA1 */
        calc_HA1(HA_MD5, &_username->whole, _domain, &sval.rs, 0, 0, _ha1);
        LM_DBG("HA1 string calculated: %s\n", _ha1);
    } else {
        memcpy(_ha1, sval.rs.s, sval.rs.len);
        _ha1[sval.rs.len] = '\0';
    }

    return 0;
}
Example #2
0
/**
 * @brief do WWW-Digest authentication with password taken from cfg var
 */
static int pv_authenticate(struct sip_msg *msg, char *p1, char *p2,
		char *p3, int hftype)
{
    int flags = 0;
    str realm  = {0, 0};
    str passwd = {0, 0};
	struct hdr_field* h;
	auth_body_t* cred;
	int ret;
    str hf = {0, 0};
    avp_value_t val;
	static char ha1[256];
	struct qp *qop = NULL;

	cred = 0;
	ret = AUTH_ERROR;

	if (get_str_fparam(&realm, msg, (fparam_t*)p1) < 0) {
		LM_ERR("failed to get realm value\n");
		goto error;
	}

	if(realm.len==0) {
		LM_ERR("invalid realm value - empty content\n");
		goto error;
	}

	if (get_str_fparam(&passwd, msg, (fparam_t*)p2) < 0) {
		LM_ERR("failed to get passwd value\n");
		goto error;
	}

	if(passwd.len==0) {
		LM_ERR("invalid password value - empty content\n");
		goto error;
	}

	if (get_int_fparam(&flags, msg, (fparam_t*)p3) < 0) {
		LM_ERR("invalid flags value\n");
		goto error;
	}

	switch(pre_auth(msg, &realm, hftype, &h, NULL)) {
		case ERROR:
		case BAD_CREDENTIALS:
			LM_DBG("error or bad credentials\n");
			ret = AUTH_ERROR;
			goto end;
		case CREATE_CHALLENGE:
			LM_ERR("CREATE_CHALLENGE is not a valid state\n");
			ret = AUTH_ERROR;
			goto end;
		case DO_RESYNCHRONIZATION:
			LM_ERR("DO_RESYNCHRONIZATION is not a valid state\n");
			ret = AUTH_ERROR;
			goto end;
		case NOT_AUTHENTICATED:
			LM_DBG("not authenticated\n");
			ret = AUTH_ERROR;
			goto end;
		case DO_AUTHENTICATION:
			break;
		case AUTHENTICATED:
			ret = AUTH_OK;
			goto end;
	}

	cred = (auth_body_t*)h->parsed;

	/* compute HA1 if needed */
	if ((flags&1)==0) {
		/* Plaintext password is stored in PV, calculate HA1 */
		calc_HA1(HA_MD5, &cred->digest.username.whole, &realm,
				&passwd, 0, 0, ha1);
		LM_DBG("HA1 string calculated: %s\n", ha1);
	} else {
		memcpy(ha1, passwd.s, passwd.len);
		ha1[passwd.len] = '\0';
	}

	/* Recalculate response, it must be same to authorize successfully */
	ret = auth_check_response(&(cred->digest),
				&msg->first_line.u.request.method, ha1);
	if(ret==AUTHENTICATED) {
		ret = AUTH_OK;
		switch(post_auth(msg, h)) {
			case AUTHENTICATED:
				break;
			default:
				ret = AUTH_ERROR;
				break;
		}
	} else {
		if(ret==NOT_AUTHENTICATED)
			ret = AUTH_INVALID_PASSWORD;
		else
			ret = AUTH_ERROR;
	}

end:
	if (ret < 0) {
		/* check if required to add challenge header as avp */
		if(!(flags&14))
			return ret;
		if(flags&8) {
			qop = &auth_qauthint;
		} else if(flags&4) {
			qop = &auth_qauth;
		}
		if (get_challenge_hf(msg, (cred ? cred->stale : 0),
				&realm, NULL, NULL, qop, hftype, &hf) < 0) {
			ERR("Error while creating challenge\n");
			ret = AUTH_ERROR;
		} else {
			val.s = hf;
			if(add_avp(challenge_avpid.flags | AVP_VAL_STR,
							challenge_avpid.name, val) < 0) {
				LM_ERR("Error while creating attribute with challenge\n");
				ret = AUTH_ERROR;
			}
			pkg_free(hf.s);
		}
	}

error:
	return ret;

}
Example #3
0
static inline int get_ha1(struct username* _username, str* _domain,
			  char* _table, char* _ha1, db_res_t** res)
{
	struct aaa_avp *cred;
	db_key_t keys[2];
	db_val_t vals[2];
	db_key_t *col;
	str result;
	int n, nc;

	col = pkg_malloc(sizeof(*col) * (credentials_n + 1));
	if (col == NULL) {
		LOG(L_ERR, "get_ha1(): Error while allocating memory\n");
		return -1;
	}

	keys[0] = user_column.s;
	keys[1] = domain_column.s;
	col[0] = (_username->domain.len && !calc_ha1) ?
		(pass_column_2.s) : (pass_column.s);

	for (n = 0, cred=credentials; cred ; n++, cred=cred->next) {
		col[1 + n] = cred->attr_name.s;
	}

	VAL_TYPE(vals) = VAL_TYPE(vals + 1) = DB_STR;
	VAL_NULL(vals) = VAL_NULL(vals + 1) = 0;

	VAL_STR(vals).s = _username->user.s;
	VAL_STR(vals).len = _username->user.len;

	if (_username->domain.len) {
		VAL_STR(vals + 1) = _username->domain;
	} else {
		VAL_STR(vals + 1) = *_domain;
	}

	n = (use_domain ? 2 : 1);
	nc = 1 + credentials_n;
	if (auth_dbf.use_table(auth_db_handle, _table) < 0) {
		LOG(L_ERR, "get_ha1(): Error in use_table\n");
		pkg_free(col);
		return -1;
	}

	if (auth_dbf.query(auth_db_handle, keys, 0, vals, col, n, nc, 0, res) < 0) {
		LOG(L_ERR, "get_ha1(): Error while querying database\n");
		pkg_free(col);
		return -1;
	}
	pkg_free(col);

	if (RES_ROW_N(*res) == 0) {
		DBG("get_ha1(): no result for user \'%.*s@%.*s\'\n",
			_username->user.len, ZSW(_username->user.s),
			(use_domain ? (_domain->len) : 0), ZSW(_domain->s));
		return 1;
	}

	result.s = (char*)ROW_VALUES(RES_ROWS(*res))[0].val.string_val;
	result.len = strlen(result.s);

	if (calc_ha1) {
		/* Only plaintext passwords are stored in database,
		 * we have to calculate HA1 */
		calc_HA1(HA_MD5, &_username->whole, _domain, &result, 0, 0, _ha1);
		DBG("HA1 string calculated: %s\n", _ha1);
	} else {
		memcpy(_ha1, result.s, result.len);
		_ha1[result.len] = '\0';
	}

	return 0;
}
Example #4
0
/**
 * @brief do WWW-Digest authentication with password taken from cfg var
 */
int pv_authenticate(struct sip_msg *msg, str *realm, str *passwd,
		int flags, int hftype, str *method)
{
	struct hdr_field* h;
	auth_body_t* cred;
	int ret;
	str hf = {0, 0};
	avp_value_t val;
	static char ha1[256];
	struct qp *qop = NULL;

	cred = 0;
	ret = AUTH_ERROR;

	switch(pre_auth(msg, realm, hftype, &h, NULL)) {
		case NONCE_REUSED:
			LM_DBG("nonce reused");
			ret = AUTH_NONCE_REUSED;
			goto end;
		case STALE_NONCE:
			LM_DBG("stale nonce\n");
			ret = AUTH_STALE_NONCE;
			goto end;
		case NO_CREDENTIALS:
			LM_DBG("no credentials\n");
			ret = AUTH_NO_CREDENTIALS;
			goto end;
		case ERROR:
		case BAD_CREDENTIALS:
			LM_DBG("error or bad credentials\n");
			ret = AUTH_ERROR;
			goto end;
		case CREATE_CHALLENGE:
			LM_ERR("CREATE_CHALLENGE is not a valid state\n");
			ret = AUTH_ERROR;
			goto end;
		case DO_RESYNCHRONIZATION:
			LM_ERR("DO_RESYNCHRONIZATION is not a valid state\n");
			ret = AUTH_ERROR;
			goto end;
		case NOT_AUTHENTICATED:
			LM_DBG("not authenticated\n");
			ret = AUTH_ERROR;
			goto end;
		case DO_AUTHENTICATION:
			break;
		case AUTHENTICATED:
			ret = AUTH_OK;
			goto end;
	}

	cred = (auth_body_t*)h->parsed;

	/* compute HA1 if needed */
	if ((flags&1)==0) {
		/* Plaintext password is stored in PV, calculate HA1 */
		calc_HA1(HA_MD5, &cred->digest.username.whole, realm,
				passwd, 0, 0, ha1);
		LM_DBG("HA1 string calculated: %s\n", ha1);
	} else {
		memcpy(ha1, passwd->s, passwd->len);
		ha1[passwd->len] = '\0';
	}

	/* Recalculate response, it must be same to authorize successfully */
	ret = auth_check_response(&(cred->digest), method, ha1);
	if(ret==AUTHENTICATED) {
		ret = AUTH_OK;
		switch(post_auth(msg, h)) {
			case AUTHENTICATED:
				break;
			default:
				ret = AUTH_ERROR;
				break;
		}
	} else {
		if(ret==NOT_AUTHENTICATED)
			ret = AUTH_INVALID_PASSWORD;
		else
			ret = AUTH_ERROR;
	}

end:
	if (ret < 0) {
		/* check if required to add challenge header as avp */
		if(!(flags&14))
			return ret;
		if(flags&8) {
			qop = &auth_qauthint;
		} else if(flags&4) {
			qop = &auth_qauth;
		}
		if (get_challenge_hf(msg, (cred ? cred->stale : 0),
					realm, NULL, NULL, qop, hftype, &hf) < 0) {
			ERR("Error while creating challenge\n");
			ret = AUTH_ERROR;
		} else {
			val.s = hf;
			if(add_avp(challenge_avpid.flags | AVP_VAL_STR,
						challenge_avpid.name, val) < 0) {
				LM_ERR("Error while creating attribute with challenge\n");
				ret = AUTH_ERROR;
			}
			pkg_free(hf.s);
		}
	}

	return ret;
}
/***
void CPocketSMDlg::OnButtonDeleteContact() 
{
	// TODO: Add your control notification handler code here
	int nIndex = m_ctlComboTo.GetCurSel();	
	if(nIndex == CB_ERR)
	{
		AfxMessageBox(_T("No contact selected from the list."));
		return;
	}

	if(m_ctlComboTo.DeleteString(nIndex) == CB_ERR)
	{
		AfxMessageBox(_T("The contact could not be deleted."));
		return;
	}
	m_ctlComboTo.SetCurSel(0);
	
}
***/
int CPocketSMDlg::computeAuthHeader( CString sipRepl )
{
	CString  wwwAuth;
	CString  authHdr;
	CString  newSipReq;
	int h,t,l,n;
	int quote;
	CString  s;
	CString strTmp;
	CString  par;
	CString  cnonce = "SAIDF3W2R8FAETR329FAHSDF34";
	/* header params */
	CString  param[]={"realm","nonce","opaque","algorithm","qop","stale"};
	CString  vals[]={"","","","","",""};
	CString  strURI = "sip:";
	int     quoted[]={1,1,1,0,1,0};
	HASHHEX hashHex1;
	HASHHEX hashHex2;
	str strMethod = {"REGISTER", 8};
	char userBuf[30], passwdBuf[30], nonceBuf[50], cnonceBuf[50], uriBuf[50], realmBuf[50];
	str sUser = {userBuf, 30}, sPasswd = {passwdBuf, 30}, sRealm = {realmBuf, 50},
		sNonce = {nonceBuf, 50}, sCnonce = {cnonceBuf, 50}, sURI = {uriBuf, 50};

	m_strAuthHdr = "";
	strURI += m_strSrvPart;

	//AddInfoMessage(sipRepl);
	//UpdateDisplayedMessage();

	/* get the www-auth header from reply */
	h = sipRepl.Find(_T("WWW-Authenticate"));
	if (h==-1)
		return -1;

	strTmp = sipRepl.Right(sipRepl.GetLength()-h);
	t = strTmp.Find('\n');
	if(strTmp.GetAt(t-1) == '\r')
		t--;
	wwwAuth = sipRepl.Mid(h,t);

	/* parse the www_auth header */
	s = wwwAuth;
	h = s.Find(_T("Digest"));
	if (h==-1)
		return -2;
	h += 6;
	/* comput the length of useful part */
	l = s.GetLength();
	while (s.GetAt(l-1)=='\n' || s.GetAt(l-1)=='\r')
		l--;
	/* look for all the params */
	while(h<l) {
		/* search the begining of the next param */
		while( h<l && (s.GetAt(h)==' ' || s.GetAt(h)=='\t') )
			h++;
		if (h==l)
			return -3;
		/* get the param name */
		t = h;
		while( t<l && s.GetAt(t)!=' ' && s.GetAt(t)!='=')
			t++;
		if (t==l || t==h)
			return -4;
		par = s.Mid(h,t-h);
		h=t;
		/* are we looking for this parameter? */
		for(n=0; n<6; n++)
			if(!param[n].CompareNoCase(par))
				break;
		if(n==6)
			n = -1;

		/* eat spaces */
		while( h<l && (s.GetAt(h)==' ' || s.GetAt(h)=='\t') )
			h++;
		/* do we have a "="? */
		if (h==l || s.GetAt(h)!='=' || ++h==l)
			return -5;
		/* eat spaces */
		while( h<l && (s.GetAt(h)==' ' || s.GetAt(h)=='\t') )
			h++;
		/* param's value */
		if ( n!=-1 && ( (quoted[n]==1 && s.GetAt(h)!='"') ||
			(quoted[n]==0 && s.GetAt(h)=='"')) )
			return -6;
		if(n!=-1 && quoted[n]==1)
			h++;
		quote=(n==-1&&s.GetAt(h)=='"')||(n!=-1&&quoted[n]==1)?1:0;
		/* look for the end of value */
		t = h;
		while( t<l && (quote && s.GetAt(t)!='"' ||
			!quote && s.GetAt(t)!=' ' && s.GetAt(t)!=',') )
			t++;
		if (t==h)
			return -7;
		if (n!=-1) {
			vals[n] = s.Mid(h,t-h);
		}
		h = t + (quote?1:0);
		/* eat spaces */
		while( h<l && (s.GetAt(h)==' ' || s.GetAt(h)=='\t') )
			h++;
		if (h==l)  break;
		/* here must be a ',' */
		if (s.GetAt(h)!=',' || ++h==l)
			return -8;
	}
	/* some checkings */
	if (vals[0]=="")
		return -9;
	if (vals[1]=="")
		return -10;
	/* comput the authentication */
	translateToStr(m_strUserPart, &sUser);
	translateToStr(m_strPassword, &sPasswd);
	translateToStr(vals[0], &sRealm);
	translateToStr(vals[1], &sNonce);
	translateToStr(cnonce, &sCnonce);
	translateToStr(strURI, &sURI);

	calc_HA1(HA_MD5, &sUser, &sRealm, &sPasswd, &sNonce, &sCnonce, hashHex1);

	calc_response(hashHex1, &sNonce, NULL, &sCnonce, NULL, 0, &strMethod, &sURI, NULL, hashHex2);

	/* build authorization header */
	m_strAuthHdr = "Authorization: Digest";
	/* add username */
	m_strAuthHdr += " username=\""+m_strUserPart+"\"";
	/* add realm */
	m_strAuthHdr += ", realm=\""+vals[0]+"\"";
	/* add uri */
	m_strAuthHdr += ", uri=\"";
	m_strAuthHdr += strURI;
	m_strAuthHdr += "\"";
	/* add algorithm */
	if(vals[3].GetLength() > 0)
		m_strAuthHdr += ", algorithm=\""+vals[3]+"\"";
	else
		m_strAuthHdr += ", algorithm=\"md5\"";
	/* add nonce */
	m_strAuthHdr += ", nonce=\""+vals[1]+"\"";
	/* add opaque, if needed */
	if (vals[2]!="")
		m_strAuthHdr += ", opaque=\""+vals[2]+"\"";
	/* add qop, if needed */
	if (vals[4]!="") {
		m_strAuthHdr += ", qop=\""+vals[4]+"\"";
		m_strAuthHdr += ", cnonce=\""+cnonce+"\"";
	}
	/* add response */
	m_strAuthHdr += ", response=\"";
	m_strAuthHdr += hashHex2;
	m_strAuthHdr += "\"";
	return 0;
}