#include <Windows.h>
#include "./../md5/jauth.h"
#include <eXosip2/eXosip.h>
#pragma comment(lib, "eXosip2.lib")
#pragma comment(lib, "osipparser2.lib")
const char *const password = "password";
const char *const realm = "SipServer";
const int uas_port = 10086;
// WWW-Authenticate: Digest
// realm="10.13.5.1", // 主机名或域名
// nonce="61f47e1e8598aad82a2b87482cb87fad", // 服务器端指定的数据字符, 401
// opaque="61f47e1e8598aad82a2b87482cb87fad", // 可以不用
// qop="auth,auth-int" // auth: 鉴别方式, auth-int: 鉴别保护的完整性
// [truncated]Authorization: Digest
// username="user",
// realm="10.13.5.1",
// nonce="61f47e1e8598aad82a2b87482cb87fad",
// uri="sip:user@10.13.5.1:10086",
// response="37b9120e9107be627e1af8f95913fc47",
// algorithm=MD5,
// cnonce="0a4f113b",
// opaque="61f47e1e8598aad82a2b87482cb87fad",
// qop=auth,
// nc=00000001
void SendRegisterAnswer(eXosip_event_t *je, int status)
{
osip_message_t *answer = NULL;
eXosip_lock();
int ret = eXosip_message_build_answer(je->tid, status, &answer);
if (status == 401)
{
char hvalue[128] = {0};
char now[128] = {0};
HASHHEX nonce;
sprintf(now, "%d", time(NULL));
DigestCalcMD5(now, nonce);
HASHHEX opaque;
sprintf(now, "%d", time(NULL));
DigestCalcMD5(now, opaque);
sprintf(hvalue, "Digest realm=\"%s\",qop=\"%s\",nonce=\"%s\",opaque=\"%s\"", realm, "auth,auth-int", nonce, opaque);
osip_message_set_www_authenticate(answer, hvalue);
SYSTEMTIME st;
GetLocalTime(&st);
sprintf(now, "time=%.4d-%.2d-%.2d %.2d:%.2d:%.2d.%.3d", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
osip_message_set_body(answer, now, strlen(now));
osip_message_set_content_type(answer, "Application/TIME");
printf("发送401报文\n");
}
else if (status == 200)
{
SYSTEMTIME st;
GetLocalTime(&st);
char time[128] = {0};
sprintf(time, "time=%.4d-%.2d-%.2d %.2d:%.2d:%.2d.%.3d", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
osip_message_set_body(answer, time, strlen(time));
osip_message_set_content_type(answer, "Application/TIME");
printf("发送200报文\n");
}
if (ret != 0)
{
eXosip_message_send_answer(je->tid, 400, NULL);
}
else
{
eXosip_message_send_answer(je->tid, status, answer);
}
eXosip_unlock();
}
int main(int argc, char **argv)
{
int ret = -1;
ret = eXosip_init();
if (ret == 0)
{
printf("eXosip_init success\n");
}
else
{
printf("eXosip_init failed, code:%d", ret);
}
ret = eXosip_listen_addr(IPPROTO_UDP, NULL, uas_port, AF_INET, 0);
if (ret == 0)
{
printf("eXosip_listen_addr success, listen port:%d\n", uas_port);
}
else
{
printf("eXosip_listen_addr failed, code:%d\n", ret);
}
eXosip_event_t *je = NULL;
for (;;)
{
je = eXosip_event_wait(0, 200);
eXosip_lock();
eXosip_default_action(je);
eXosip_automatic_refresh();
eXosip_unlock();
if (NULL == je)
{
continue;
}
switch (je->type)
{
case EXOSIP_REGISTRATION_NEW:
{
printf("EXOSIP_REGISTRATION_NEW\n");
}
break;
case EXOSIP_REGISTRATION_SUCCESS:
{
if (je->response)
{
printf("EXOSIP_REGISTRATION_SUCCESS status_code:%d\n", je->response->status_code);
}
}
break;
case EXOSIP_REGISTRATION_FAILURE:
{
// 第一次注册返回401, 403表示用户名密码错误
if (je->response)
{
printf("EXOSIP_REGISTRATION_FAILURE status_code:%d\n", je->response->status_code);
}
}
break;
case EXOSIP_REGISTRATION_REFRESHED:
{
printf("EXOSIP_REGISTRATION_REFRESHED\n");
}
break;
case EXOSIP_REGISTRATION_TERMINATED:
{
printf("EXOSIP_REGISTRATION_TERMINATED\n");
}
break;
case EXOSIP_MESSAGE_NEW:
{
if (MSG_IS_REGISTER(je->request))
{
osip_authorization_t *auth = NULL;
osip_message_get_authorization(je->request, 0, &auth);
if (auth == NULL) // 401
{
SendRegisterAnswer(je, 401);
}
else
{
char *username = NULL;
char *realm = NULL;
char *nonce = NULL;
char *nonce_count = NULL;
char *cnonce = NULL;
char *qop = NULL;
char *uri = NULL;
char *response = NULL;
char *pszAlg = "MD5";
char *pszUserName = NULL;
char *pszRealm = NULL;
HASHHEX pszPassword;
DigestCalcMD5(password, pszPassword);
char *pszNonce = NULL;
char *pszNonceCount = NULL;
char *pszCNonce = NULL;
char *pszQop = NULL;
char *pszDigestUri = NULL;
char *pszResponse = NULL;
username = osip_authorization_get_username(auth);
if (username)
{
pszUserName = osip_strdup_without_quote(username);
}
realm = osip_authorization_get_realm(auth);
if (realm)
{
pszRealm = osip_strdup_without_quote(realm);
}
nonce = osip_authorization_get_nonce(auth);
if (nonce)
{
pszNonce = osip_strdup_without_quote(nonce);
}
nonce_count = osip_authorization_get_nonce_count(auth);
if (nonce_count)
{
pszNonceCount = osip_strdup_without_quote(nonce_count);
}
cnonce = osip_authorization_get_cnonce(auth);
if (cnonce)
{
pszCNonce = osip_strdup_without_quote(cnonce);
}
qop = osip_authorization_get_message_qop(auth);
if (qop)
{
pszQop = osip_strdup_without_quote(qop);
}
uri = osip_authorization_get_uri(auth);
if (uri)
{
pszDigestUri = osip_strdup_without_quote(uri);
}
HASHHEX HA1;
HASHHEX Response;
DigestCalcHA1(pszAlg, pszUserName, pszRealm, pszPassword, pszNonce, pszCNonce, HA1);
DigestCalcResponse(HA1, pszNonce, pszNonceCount, pszCNonce, pszQop, 0, je->request->sip_method, pszDigestUri, NULL, Response);
response = osip_authorization_get_response(auth);
if (response)
{
pszResponse = osip_strdup_without_quote(response);
}
printf("%s\n%s\n", pszResponse, Response);
if (stricmp(pszResponse, Response) == 0)
{
osip_via_t *via = NULL;
osip_message_get_via(je->request, 0, &via);
if (via)
{
printf("user:%s, host:%s, port:%s\n", pszUserName, via->host, via->port);
osip_generic_param_t *received = NULL;
osip_generic_param_t *rport = NULL;
osip_via_param_get_byname(via, "received", &received);
osip_via_param_get_byname(via, "rport", &rport);
if (received && rport)
{
printf("ip:%d, port:%d\n", received->gvalue, rport->gvalue);
}
}
SendRegisterAnswer(je, 200);
}
else
{
printf("用户名密码错误\n");
SendRegisterAnswer(je, 403);
}
}
}
else if (MSG_IS_MESSAGE(je->request))
{
}
}
break;
default:
{
printf("the sip event type:%d\n", je->type);
}
break;
}
eXosip_event_free(je);
je = NULL;
}
return 0;
}