/* $Id$ */
/* 
 * Copyright (C) 2003-2007 Benny Prijono <benny@prijono.org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
 */
#include "test.h"

#define THIS_FILE   "sess_auth.c"

#define REALM	    "STUN session test"
#define USERNAME    "theusername"
#define PASSWORD    "thepassword"
#define NONCE	    "thenonce"


/* STUN config */
static pj_stun_config stun_cfg;


//////////////////////////////////////////////////////////////////////////////////////////
//
// SERVER PART
//


/* Server instance */
static struct server
{
    pj_pool_t		*pool;
    pj_sockaddr		 addr;
    pj_stun_session	*sess;

    pj_bool_t		 responding;
    unsigned		 recv_count;
    pj_stun_auth_type	 auth_type;

    pj_sock_t		 sock;

    pj_bool_t		 quit;
    pj_thread_t		*thread;
} *server;


static pj_status_t server_send_msg(pj_stun_session *sess,
				   void *token,
				   const void *pkt,
				   pj_size_t pkt_size,
				   const pj_sockaddr_t *dst_addr,
				   unsigned addr_len)
{
    pj_ssize_t len = pkt_size;

    PJ_UNUSED_ARG(sess);
    PJ_UNUSED_ARG(token);

    return pj_sock_sendto(server->sock, pkt, &len, 0, dst_addr, addr_len);
}

static pj_status_t server_on_rx_request(pj_stun_session *sess,
					const pj_uint8_t *pkt,
					unsigned pkt_len,
					const pj_stun_rx_data *rdata,
					void *token,
					const pj_sockaddr_t *src_addr,
					unsigned src_addr_len)
{
    PJ_UNUSED_ARG(pkt);
    PJ_UNUSED_ARG(pkt_len);
    PJ_UNUSED_ARG(token);

    return pj_stun_session_respond(sess, rdata, 0, NULL, NULL, PJ_TRUE, 
				   src_addr, src_addr_len);
}


static pj_status_t server_get_auth(void *user_data,
				   pj_pool_t *pool,
				   pj_str_t *realm,
				   pj_str_t *nonce)
{
    PJ_UNUSED_ARG(user_data);
    PJ_UNUSED_ARG(pool);

    if (server->auth_type == PJ_STUN_AUTH_SHORT_TERM) {
	realm->slen = nonce->slen = 0;
    } else {
	*realm = pj_str(REALM);
	*nonce = pj_str(NONCE);
    }

    return PJ_SUCCESS;
}


static pj_status_t server_get_password( const pj_stun_msg *msg,
					void *user_data, 
				        const pj_str_t *realm,
				        const pj_str_t *username,
					pj_pool_t *pool,
					pj_stun_passwd_type *data_type,
					pj_str_t *data)
{
    PJ_UNUSED_ARG(msg);
    PJ_UNUSED_ARG(user_data);
    PJ_UNUSED_ARG(pool);

    if (server->auth_type == PJ_STUN_AUTH_SHORT_TERM) {
	if (realm && realm->slen) {
	    PJ_LOG(4,(THIS_FILE, "    server expecting short term"));
	    return -1;
	}
    } else {
	if (realm==NULL || realm->slen==0) {
	    PJ_LOG(4,(THIS_FILE, "    realm not present"));
	    return -1;
	}
    }

    if (pj_strcmp2(username, USERNAME) != 0) {
	PJ_LOG(4,(THIS_FILE, "    wrong username"));
	return -1;
    }

    *data_type = PJ_STUN_PASSWD_PLAIN;
    *data = pj_str(PASSWORD);

    return PJ_SUCCESS;
}


static pj_bool_t server_verify_nonce(const pj_stun_msg *msg,
				     void *user_data,
				     const pj_str_t *realm,
				     const pj_str_t *username,
				     const pj_str_t *nonce)
{
    PJ_UNUSED_ARG(msg);
    PJ_UNUSED_ARG(user_data);
    PJ_UNUSED_ARG(realm);
    PJ_UNUSED_ARG(username);

    if (pj_strcmp2(nonce, NONCE) != 0)
	return PJ_FALSE;

    return PJ_TRUE;
}


static int server_thread(void *unused)
{
    PJ_UNUSED_ARG(unused);

    while (!server->quit) {
	pj_fd_set_t readset;
	pj_time_val delay = {0, 10};

	PJ_FD_ZERO(&readset);
	PJ_FD_SET(server->sock, &readset);

	if (pj_sock_select(server->sock, &readset, NULL, NULL, &delay)==1 &&
	    PJ_FD_ISSET(server->sock, &readset)) 
	{
	    char pkt[1000];
	    pj_ssize_t len;
	    pj_status_t status;
	    pj_sockaddr src_addr;
	    int src_addr_len;

	    len = sizeof(pkt);
	    src_addr_len = sizeof(src_addr);

	    status = pj_sock_recvfrom(server->sock, pkt, &len, 0, &src_addr, &src_addr_len);
	    if (status != PJ_SUCCESS)
		continue;

	    /* Increment server's receive count */
	    server->recv_count++;

	    /* Only pass to server if we allow to respond */
	    if (!server->responding)
		continue;

	    pj_stun_session_on_rx_pkt(server->sess, pkt, len, 
				      PJ_STUN_CHECK_PACKET | PJ_STUN_IS_DATAGRAM,
				      NULL, NULL, &src_addr, src_addr_len);
	}
    }

    return 0;
}


/* Destroy server */
static void destroy_server(void)
{
    if (server->thread) {
	server->quit = PJ_TRUE;
	pj_thread_join(server->thread);
	pj_thread_destroy(server->thread);
    }

    if (server->sock) {
	pj_sock_close(server->sock);
    }

    if (server->sess) {
	pj_stun_session_destroy(server->sess);
    }

    pj_pool_release(server->pool);
    server = NULL;
}

/* Instantiate standard server */
static int create_std_server(pj_stun_auth_type auth_type,
			     pj_bool_t responding)
{
    pj_pool_t *pool;
    pj_stun_session_cb sess_cb;
    pj_stun_auth_cred cred;
    pj_status_t status;
    
    /* Create server */
    pool = pj_pool_create(mem, "server", 1000, 1000, NULL);
    server = PJ_POOL_ZALLOC_T(pool, struct server);
    server->pool = pool;
    server->auth_type = auth_type;
    server->responding = responding;

    /* Create STUN session */
    pj_bzero(&sess_cb, sizeof(sess_cb));
    sess_cb.on_rx_request = &server_on_rx_request;
    sess_cb.on_send_msg = &server_send_msg;
    status = pj_stun_session_create(&stun_cfg, "server", &sess_cb, PJ_FALSE, &server->sess);
    if (status != PJ_SUCCESS) {
	destroy_server();
	return -10;
    }

    /* Configure credential */
    pj_bzero(&cred, sizeof(cred));
    cred.type = PJ_STUN_AUTH_CRED_DYNAMIC;
    cred.data.dyn_cred.get_auth = &server_get_auth;
    cred.data.dyn_cred.get_password = &server_get_password;
    cred.data.dyn_cred.verify_nonce = &server_verify_nonce;
    status = pj_stun_session_set_credential(server->sess, auth_type, &cred);
    if (status != PJ_SUCCESS) {
	destroy_server();
	return -20;
    }

    /* Create socket */
    status = pj_sock_socket(pj_AF_INET(), pj_SOCK_DGRAM(), 0, &server->sock);
    if (status != PJ_SUCCESS) {
	destroy_server();
	return -30;
    }

    /* Bind */
    pj_sockaddr_in_init(&server->addr.ipv4, NULL, 0);
    status = pj_sock_bind(server->sock, &server->addr, pj_sockaddr_get_len(&server->addr));
    if (status != PJ_SUCCESS) {
	destroy_server();
	return -40;
    } else {
	/* Get the bound IP address */
	int namelen = sizeof(server->addr);
	pj_sockaddr addr;

	status = pj_sock_getsockname(server->sock, &server->addr, &namelen);
	if (status != PJ_SUCCESS) {
	    destroy_server();
	    return -43;
	}

	status = pj_gethostip(pj_AF_INET(), &addr);
	if (status != PJ_SUCCESS) {
	    destroy_server();
	    return -45;
	}

	pj_sockaddr_copy_addr(&server->addr, &addr);
    }


    /* Create worker thread */
    status = pj_thread_create(pool, "server", &server_thread, 0, 0, 0, &server->thread);
    if (status != PJ_SUCCESS) {
	destroy_server();
	return -30;
    }

    return 0;
}


//////////////////////////////////////////////////////////////////////////////////////////
//
// CLIENT PART
//

static struct client
{
    pj_pool_t	    *pool;
    pj_stun_session *sess;
    pj_sem_t	    *test_complete;
    pj_sock_t	     sock;

    pj_bool_t	     responding;
    unsigned	     recv_count;

    pj_status_t	     response_status;
    pj_stun_msg	    *response;

    pj_bool_t	     quit;
    pj_thread_t	    *thread;
} *client;


static pj_status_t client_send_msg(pj_stun_session *sess,
				   void *token,
				   const void *pkt,
				   pj_size_t pkt_size,
				   const pj_sockaddr_t *dst_addr,
				   unsigned addr_len)
{
    pj_ssize_t len = pkt_size;

    PJ_UNUSED_ARG(sess);
    PJ_UNUSED_ARG(token);

    return pj_sock_sendto(client->sock, pkt, &len, 0, dst_addr, addr_len);
}


static void client_on_request_complete( pj_stun_session *sess,
					pj_status_t status,
					void *token,
					pj_stun_tx_data *tdata,
					const pj_stun_msg *response,
					const pj_sockaddr_t *src_addr,
					unsigned src_addr_len)
{
    PJ_UNUSED_ARG(sess);
    PJ_UNUSED_ARG(token);
    PJ_UNUSED_ARG(tdata);
    PJ_UNUSED_ARG(src_addr);
    PJ_UNUSED_ARG(src_addr_len);

    client->response_status = status;
    if (response)
	client->response = pj_stun_msg_clone(client->pool, response);

    pj_sem_post(client->test_complete);
}


static int client_thread(void *unused)
{
    PJ_UNUSED_ARG(unused);

    while (!client->quit) {
	pj_fd_set_t readset;
	pj_time_val delay = {0, 10};

	/* Also poll the timer heap */
	pj_timer_heap_poll(stun_cfg.timer_heap, NULL);

	/* Poll client socket */
	PJ_FD_ZERO(&readset);
	PJ_FD_SET(client->sock, &readset);

	if (pj_sock_select(client->sock, &readset, NULL, NULL, &delay)==1 &&
	    PJ_FD_ISSET(client->sock, &readset)) 
	{
	    char pkt[1000];
	    pj_ssize_t len;
	    pj_status_t status;
	    pj_sockaddr src_addr;
	    int src_addr_len;

	    len = sizeof(pkt);
	    src_addr_len = sizeof(src_addr);

	    status = pj_sock_recvfrom(client->sock, pkt, &len, 0, &src_addr, &src_addr_len);
	    if (status != PJ_SUCCESS)
		continue;

	    /* Increment client's receive count */
	    client->recv_count++;

	    /* Only pass to client if we allow to respond */
	    if (!client->responding)
		continue;

	    pj_stun_session_on_rx_pkt(client->sess, pkt, len, 
				      PJ_STUN_CHECK_PACKET | PJ_STUN_IS_DATAGRAM,
				      NULL, NULL, &src_addr, src_addr_len);
	}
 
    }

    return 0;
}


static void destroy_client_server(void)
{
    if (client->thread) {
	client->quit = 1;
	pj_thread_join(client->thread);
	pj_thread_destroy(client->thread);
    }

    if (client->sess)
	pj_stun_session_destroy(client->sess);

    if (client->sock)
	pj_sock_close(client->sock);

    if (client->test_complete)
	pj_sem_destroy(client->test_complete);

    if (server)
	destroy_server();
}

static int run_client_test(const char *title,

			   pj_bool_t server_responding,
			   pj_stun_auth_type server_auth_type,

			   pj_stun_auth_type client_auth_type,
			   const char *realm,
			   const char *username,
			   const char *nonce,
			   const char *password,
			   pj_bool_t dummy_mi,

			   pj_stun_status expected_error,
			   pj_stun_status expected_code,
			   const char *expected_realm,
			   const char *expected_nonce,
			   
			   int (*more_check)(void))
{
    pj_pool_t *pool;
    pj_stun_session_cb sess_cb;
    pj_stun_auth_cred cred;
    pj_stun_tx_data *tdata;
    pj_status_t status;
    int rc = 0;
    
    PJ_LOG(3,(THIS_FILE, "   %s test", title));

    /* Create client */
    pool = pj_pool_create(mem, "client", 1000, 1000, NULL);
    client = PJ_POOL_ZALLOC_T(pool, struct client);
    client->pool = pool;
    client->responding = PJ_TRUE;

    /* Create STUN session */
    pj_bzero(&sess_cb, sizeof(sess_cb));
    sess_cb.on_request_complete = &client_on_request_complete;
    sess_cb.on_send_msg = &client_send_msg;
    status = pj_stun_session_create(&stun_cfg, "client", &sess_cb, PJ_FALSE, &client->sess);
    if (status != PJ_SUCCESS) {
	destroy_client_server();
	return -200;
    }

    /* Create semaphore */
    status = pj_sem_create(pool, "client", 0, 1, &client->test_complete);
    if (status != PJ_SUCCESS) {
	destroy_client_server();
	return -205;
    }

    /* Create client socket */
    status = pj_sock_socket(pj_AF_INET(), pj_SOCK_DGRAM(), 0, &client->sock);
    if (status != PJ_SUCCESS) {
	destroy_client_server();
	return -210;
    }

    /* Bind client socket */
    status = pj_sock_bind_in(client->sock, 0, 0);
    if (status != PJ_SUCCESS) {
	destroy_client_server();
	return -220;
    }

    /* Create client thread */
    status = pj_thread_create(pool, "client", &client_thread, NULL, 0, 0, &client->thread);
    if (status != PJ_SUCCESS) {
	destroy_client_server();
	return -230;
    }

    /* Initialize credential */
    pj_bzero(&cred, sizeof(cred));
    cred.type = PJ_STUN_AUTH_CRED_STATIC;
    if (realm) cred.data.static_cred.realm = pj_str((char*)realm);
    if (username) cred.data.static_cred.username = pj_str((char*)username);
    if (nonce) cred.data.static_cred.nonce = pj_str((char*)nonce);
    if (password) cred.data.static_cred.data = pj_str((char*)password);
    cred.data.static_cred.data_type = PJ_STUN_PASSWD_PLAIN;
    status = pj_stun_session_set_credential(client->sess, client_auth_type, &cred);
    if (status != PJ_SUCCESS) {
	destroy_client_server();
	return -240;
    }

    /* Create the server */
    status = create_std_server(server_auth_type, server_responding);
    if (status != 0) {
	destroy_client_server();
	return status;
    }

    /* Create request */
    status = pj_stun_session_create_req(client->sess, PJ_STUN_BINDING_REQUEST, 
					PJ_STUN_MAGIC, NULL, &tdata);
    if (status != PJ_SUCCESS) {
	destroy_client_server();
	return -250;
    }

    /* Add our own attributes if client authentication is set to none */
    if (client_auth_type == PJ_STUN_AUTH_NONE) {
	pj_str_t tmp;
	if (realm)
	    pj_stun_msg_add_string_attr(tdata->pool, tdata->msg, PJ_STUN_ATTR_REALM, pj_cstr(&tmp, realm));
	if (username)
	    pj_stun_msg_add_string_attr(tdata->pool, tdata->msg, PJ_STUN_ATTR_USERNAME, pj_cstr(&tmp, username));
	if (nonce)
	    pj_stun_msg_add_string_attr(tdata->pool, tdata->msg, PJ_STUN_ATTR_NONCE, pj_cstr(&tmp, nonce));
	if (password) {
	    // ignored
	}
	if (dummy_mi) {
	    pj_stun_msgint_attr *mi;

	    pj_stun_msgint_attr_create(tdata->pool, &mi);
	    pj_stun_msg_add_attr(tdata->msg, &mi->hdr);
	}
	   
    }

    /* Send the request */
    status = pj_stun_session_send_msg(client->sess, NULL, PJ_FALSE, PJ_TRUE, &server->addr,
				      pj_sockaddr_get_len(&server->addr), tdata);
    if (status != PJ_SUCCESS) {
	destroy_client_server();
	return -270;
    }

    /* Wait until test complete */
    pj_sem_wait(client->test_complete);


    /* Verify response */
    if (expected_error) {
	if (expected_code != client->response_status) {
	    char e1[PJ_ERR_MSG_SIZE], e2[PJ_ERR_MSG_SIZE];

	    pj_strerror(expected_code, e1, sizeof(e1));
	    pj_strerror(client->response_status, e2, sizeof(e2));

	    PJ_LOG(3,(THIS_FILE, "    err: expecting %d (%s) but got %d (%s) response",
		      expected_code, e1, client->response_status, e2));
	    rc = -500;
	} 

    } else {
	int res_code = 0;
	pj_stun_realm_attr *arealm;
	pj_stun_nonce_attr *anonce;

	if (client->response_status != 0) {
	    PJ_LOG(3,(THIS_FILE, "    err: expecting successful operation but got error %d", 
		      client->response_status));
	    rc = -600;
	    goto done;
	} 

	if (PJ_STUN_IS_ERROR_RESPONSE(client->response->hdr.type)) {
	    pj_stun_errcode_attr *aerr = NULL;

	    aerr = (pj_stun_errcode_attr*)
		   pj_stun_msg_find_attr(client->response, 
					 PJ_STUN_ATTR_ERROR_CODE, 0);
	    if (aerr == NULL) {
		PJ_LOG(3,(THIS_FILE, "    err: received error response without ERROR-CODE"));
		rc = -610;
		goto done;
	    }

	    res_code = aerr->err_code;
	} else {
	    res_code = 0;
	}

	/* Check that code matches */
	if (expected_code != res_code) {
	    PJ_LOG(3,(THIS_FILE, "    err: expecting response code %d but got %d",
		      expected_code, res_code));
	    rc = -620;
	    goto done;
	}

	/* Find REALM and NONCE attributes */
	arealm = (pj_stun_realm_attr*)
	         pj_stun_msg_find_attr(client->response, PJ_STUN_ATTR_REALM, 0);
	anonce = (pj_stun_nonce_attr*)
	         pj_stun_msg_find_attr(client->response, PJ_STUN_ATTR_NONCE, 0);

	if (expected_realm) {
	    if (arealm == NULL) {
		PJ_LOG(3,(THIS_FILE, "    err: expecting REALM in esponse"));
		rc = -630;
		goto done;
	    }
	    if (pj_strcmp2(&arealm->value, expected_realm)!=0) {
		PJ_LOG(3,(THIS_FILE, "    err: REALM mismatch in response"));
		rc = -640;
		goto done;
	    }
	} else {
	    if (arealm != NULL) {
		PJ_LOG(3,(THIS_FILE, "    err: non expecting REALM in response"));
		rc = -650;
		goto done;
	    }
	}

	if (expected_nonce) {
	    if (anonce == NULL) {
		PJ_LOG(3,(THIS_FILE, "    err: expecting NONCE in esponse"));
		rc = -660;
		goto done;
	    }
	    if (pj_strcmp2(&anonce->value, expected_nonce)!=0) {
		PJ_LOG(3,(THIS_FILE, "    err: NONCE mismatch in response"));
		rc = -670;
		goto done;
	    }
	} else {
	    if (anonce != NULL) {
		PJ_LOG(3,(THIS_FILE, "    err: non expecting NONCE in response"));
		rc = -680;
		goto done;
	    }
	}
    }

    /* Our tests are okay so far. Let caller do some more tests if
     * it wants to.
     */
    if (rc==0 && more_check) {
	rc = (*more_check)();
    }


done:
    destroy_client_server();
    return rc;
}


//////////////////////////////////////////////////////////////////////////////////////////
//
// More verification
//

/* Retransmission test */
static int retransmit_check(void)
{
    if (server->recv_count != PJ_STUN_MAX_TRANSMIT_COUNT)
	return -700;
    if (client->recv_count != 0)
	return -710;

    return 0;
}

static int long_term_check1(void)
{
    /* SHOULD NOT contain USERNAME or MESSAGE-INTEGRITY */
    if (pj_stun_msg_find_attr(client->response, PJ_STUN_ATTR_USERNAME, 0))
	return -800;
    if (pj_stun_msg_find_attr(client->response, PJ_STUN_ATTR_MESSAGE_INTEGRITY, 0))
	return -800;

    return 0;
}

static int long_term_check2(void)
{
    /* response SHOULD NOT include a USERNAME, NONCE, REALM or 
     * MESSAGE-INTEGRITY attribute. 
     */
    if (pj_stun_msg_find_attr(client->response, PJ_STUN_ATTR_USERNAME, 0))
	return -900;
    if (pj_stun_msg_find_attr(client->response, PJ_STUN_ATTR_NONCE, 0))
	return -910;
    if (pj_stun_msg_find_attr(client->response, PJ_STUN_ATTR_REALM, 0))
	return -920;
    if (pj_stun_msg_find_attr(client->response, PJ_STUN_ATTR_MESSAGE_INTEGRITY, 0))
	return -930;

    return 0;
}

static int long_term_check3(void)
{
    /* response SHOULD NOT include a USERNAME, NONCE, and REALM */
    if (pj_stun_msg_find_attr(client->response, PJ_STUN_ATTR_USERNAME, 0))
	return -1000;
    if (pj_stun_msg_find_attr(client->response, PJ_STUN_ATTR_NONCE, 0))
	return -1010;
    if (pj_stun_msg_find_attr(client->response, PJ_STUN_ATTR_REALM, 0))
	return -1020;

    return 0;
}

//////////////////////////////////////////////////////////////////////////////////////////
//
// TEST MAIN
//


int sess_auth_test(void)
{
    pj_pool_t *pool;
    int rc;

    PJ_LOG(3,(THIS_FILE, "  STUN session authentication test"));

    /* Init STUN config */
    pj_stun_config_init(&stun_cfg, mem, 0, NULL, NULL);

    /* Create pool and timer heap */
    pool = pj_pool_create(mem, "authtest", 200, 200, NULL);
    if (pj_timer_heap_create(pool, 20, &stun_cfg.timer_heap)) {
	pj_pool_release(pool);
	return -5;
    }

    /* Basic retransmission test */
    rc = run_client_test("Retransmission",  // title
			 PJ_FALSE,	    // server responding
			 PJ_STUN_AUTH_NONE, // server auth
			 PJ_STUN_AUTH_NONE, // client auth
			 NULL,		    // realm
			 NULL,		    // username
			 NULL,		    // nonce
			 NULL,		    // password
			 PJ_FALSE,	    // dummy MI
			 PJ_TRUE,	    // expected error
			 PJNATH_ESTUNTIMEDOUT,// expected code
			 NULL,		    // expected realm
			 NULL,		    // expected nonce
			 &retransmit_check  // more check
			 );
    if (rc != 0) {
	goto done;
    }

    /*
     * Short term credential.
     * draft-ietf-behave-rfc3489bis-15#section-10.1.2
     */

    /*
     * If the message does not contain both a MESSAGE-INTEGRITY and a
     * USERNAME attribute, If the message is a request, the server MUST
     * reject the request with an error response.  This response MUST
     * use an error code of 400 (Bad Request).
     */
    rc = run_client_test("Missing MESSAGE-INTEGRITY (short term)",  // title
			 PJ_TRUE,	    // server responding
			 PJ_STUN_AUTH_SHORT_TERM, // server auth
			 PJ_STUN_AUTH_NONE, // client auth
			 NULL,		    // realm
			 NULL,		    // username
			 NULL,		    // nonce
			 NULL,		    // password
			 PJ_FALSE,	    // dummy MI
			 PJ_TRUE,	    // expected error
			 PJ_STATUS_FROM_STUN_CODE(400),// expected code
			 NULL,		    // expected realm
			 NULL,		    // expected nonce
			 NULL		    // more check
			 );
    if (rc != 0) {
	goto done;
    }

    /* If the USERNAME does not contain a username value currently valid
     * within the server: If the message is a request, the server MUST 
     * reject the request with an error response.  This response MUST use
     * an error code of 401 (Unauthorized).
     */
    rc = run_client_test("USERNAME mismatch (short term)",  // title
			 PJ_TRUE,	    // server responding
			 PJ_STUN_AUTH_SHORT_TERM, // server auth
			 PJ_STUN_AUTH_SHORT_TERM, // client auth
			 NULL,		    // realm
			 "anotheruser",	    // username
			 NULL,		    // nonce
			 "anotherpass",	    // password
			 PJ_FALSE,	    // dummy MI
			 PJ_TRUE,	    // expected error
			 PJ_STATUS_FROM_STUN_CODE(401),// expected code
			 NULL,		    // expected realm
			 NULL,		    // expected nonce
			 NULL		    // more check
			 );
    if (rc != 0) {
	goto done;
    }

    /* Using the password associated with the username, compute the value
     * for the message-integrity as described in Section 15.4.  If the
     * resulting value does not match the contents of the MESSAGE-
     * INTEGRITY attribute:
     *
     * - If the message is a request, the server MUST reject the request
     *   with an error response.  This response MUST use an error code
     *   of 401 (Unauthorized).
     */
    rc = run_client_test("MESSAGE-INTEGRITY mismatch (short term)",  // title
			 PJ_TRUE,	    // server responding
			 PJ_STUN_AUTH_SHORT_TERM, // server auth
			 PJ_STUN_AUTH_SHORT_TERM, // client auth
			 NULL,		    // realm
			 USERNAME,	    // username
			 NULL,		    // nonce
			 "anotherpass",	    // password
			 PJ_FALSE,	    // dummy MI
			 PJ_TRUE,	    // expected error
			 PJ_STATUS_FROM_STUN_CODE(401),// expected code
			 NULL,		    // expected realm
			 NULL,		    // expected nonce
			 NULL		    // more check
			 );
    if (rc != 0) {
	goto done;
    }

    /* USERNAME is not present, server must respond with 400 (Bad
     * Request).
     */
    rc = run_client_test("Missing USERNAME (short term)",// title
			 PJ_TRUE,	    // server responding
			 PJ_STUN_AUTH_SHORT_TERM, // server auth
			 PJ_STUN_AUTH_NONE, // client auth
			 NULL,		    // realm
			 NULL,		    // username
			 NULL,		    // nonce
			 NULL,		    // password
			 PJ_TRUE,	    // dummy MI
			 PJ_TRUE,	    // expected error
			 PJ_STATUS_FROM_STUN_CODE(400),	    // expected code
			 NULL,		    // expected realm
			 NULL,		    // expected nonce
			 NULL		    // more check
			 );
    if (rc != 0) {
	goto done;
    }

    /* Successful short term authentication */
    rc = run_client_test("Successful scenario (short term)",  // title
			 PJ_TRUE,	    // server responding
			 PJ_STUN_AUTH_SHORT_TERM, // server auth
			 PJ_STUN_AUTH_SHORT_TERM, // client auth
			 NULL,		    // realm
			 USERNAME,	    // username
			 NULL,		    // nonce
			 PASSWORD,	    // password
			 PJ_FALSE,	    // dummy MI
			 PJ_FALSE,	    // expected error
			 PJ_SUCCESS,	    // expected code
			 NULL,		    // expected realm
			 NULL,		    // expected nonce
			 NULL		    // more check
			 );
    if (rc != 0) {
	goto done;
    }

    /*
     * (our own) Extended tests for long term credential
     */

    /* When server wants to use short term credential, but request has
     * REALM, reject with .... 401 ???
     */
    rc = run_client_test("Unwanted REALM (short term)",  // title
			 PJ_TRUE,	    // server responding
			 PJ_STUN_AUTH_SHORT_TERM, // server auth
			 PJ_STUN_AUTH_NONE, // client auth
			 REALM,		    // realm
			 USERNAME,	    // username
			 NULL,		    // nonce
			 PASSWORD,	    // password
			 PJ_TRUE,	    // dummy MI
			 PJ_TRUE,	    // expected error
			 PJ_STATUS_FROM_STUN_CODE(401),	    // expected code
			 NULL,		    // expected realm
			 NULL,		    // expected nonce
			 &long_term_check2  // more check
			 );
    if (rc != 0) {
	goto done;
    }


    /*
     * Long term credential.
     * draft-ietf-behave-rfc3489bis-15#section-10.2.2
     */

    /* If the message does not contain a MESSAGE-INTEGRITY attribute, the
     * server MUST generate an error response with an error code of 401
     * (Unauthorized).  This response MUST include a REALM value.  It is
     * RECOMMENDED that the REALM value be the domain name of the
     * provider of the STUN server.  The response MUST include a NONCE,
     * selected by the server.  The response SHOULD NOT contain a
     * USERNAME or MESSAGE-INTEGRITY attribute.
     */
    rc = run_client_test("Missing M-I (long term)",  // title
			 PJ_TRUE,	    // server responding
			 PJ_STUN_AUTH_LONG_TERM, // server auth
			 PJ_STUN_AUTH_NONE, // client auth
			 NULL,		    // client realm
			 NULL,		    // client username
			 NULL,		    // client nonce
			 NULL,		    // client password
			 PJ_FALSE,	    // client dummy MI
			 PJ_TRUE,	    // expected error
			 PJ_STATUS_FROM_STUN_CODE(401), // expected code
			 REALM,		    // expected realm
			 NONCE,		    // expected nonce
			 &long_term_check1  // more check
			 );
    if (rc != 0) {
	goto done;
    }

    /* If the message contains a MESSAGE-INTEGRITY attribute, but is
     * missing the USERNAME, REALM or NONCE attributes, the server MUST
     * generate an error response with an error code of 400 (Bad
     * Request).  This response SHOULD NOT include a USERNAME, NONCE,
     * REALM or MESSAGE-INTEGRITY attribute.
     */
    /* Missing USERNAME */
    rc = run_client_test("Missing USERNAME (long term)",  // title
			 PJ_TRUE,	    // server responding
			 PJ_STUN_AUTH_LONG_TERM, // server auth
			 PJ_STUN_AUTH_NONE, // client auth
			 REALM,		    // client realm
			 NULL,		    // client username
			 NONCE,		    // client nonce
			 PASSWORD,	    // client password
			 PJ_TRUE,	    // client dummy MI
			 PJ_TRUE,	    // expected error
			 PJ_STATUS_FROM_STUN_CODE(400), // expected code
			 NULL,		    // expected realm
			 NULL,		    // expected nonce
			 &long_term_check2  // more check
			 );
    if (rc != 0) {
	goto done;
    }

    /* Missing REALM */
    rc = run_client_test("Missing REALM (long term)",  // title
			 PJ_TRUE,	    // server responding
			 PJ_STUN_AUTH_LONG_TERM, // server auth
			 PJ_STUN_AUTH_NONE, // client auth
			 NULL,		    // client realm
			 USERNAME,	    // client username
			 NONCE,		    // client nonce
			 PASSWORD,	    // client password
			 PJ_TRUE,	    // client dummy MI
			 PJ_TRUE,	    // expected error
			 PJ_STATUS_FROM_STUN_CODE(400), // expected code
			 NULL,		    // expected realm
			 NULL,		    // expected nonce
			 &long_term_check2  // more check
			 );
    if (rc != 0) {
	goto done;
    }

    /* Missing NONCE */
    rc = run_client_test("Missing NONCE (long term)",  // title
			 PJ_TRUE,	    // server responding
			 PJ_STUN_AUTH_LONG_TERM, // server auth
			 PJ_STUN_AUTH_NONE, // client auth
			 REALM,		    // client realm
			 USERNAME,	    // client username
			 NULL,		    // client nonce
			 PASSWORD,	    // client password
			 PJ_TRUE,	    // client dummy MI
			 PJ_TRUE,	    // expected error
			 PJ_STATUS_FROM_STUN_CODE(400), // expected code
			 NULL,		    // expected realm
			 NULL,		    // expected nonce
			 &long_term_check2  // more check
			 );
    if (rc != 0) {
	goto done;
    }

    /* If the NONCE is no longer valid, the server MUST generate an error
     * response with an error code of 438 (Stale Nonce).  This response
     * MUST include a NONCE and REALM attribute and SHOULD NOT incude the
     * USERNAME or MESSAGE-INTEGRITY attribute.  Servers can invalidate
     * nonces in order to provide additional security.  See Section 4.3
     * of [RFC2617] for guidelines.    
     */
    // how??

    /* If the username in the USERNAME attribute is not valid, the server
     * MUST generate an error response with an error code of 401
     * (Unauthorized).  This response MUST include a REALM value.  It is
     * RECOMMENDED that the REALM value be the domain name of the
     * provider of the STUN server.  The response MUST include a NONCE,
     * selected by the server.  The response SHOULD NOT contain a
     * USERNAME or MESSAGE-INTEGRITY attribute.
     */
    rc = run_client_test("Invalid username (long term)",  // title
			 PJ_TRUE,	    // server responding
			 PJ_STUN_AUTH_LONG_TERM, // server auth
			 PJ_STUN_AUTH_LONG_TERM, // client auth
			 REALM,		    // client realm
			 "anotheruser",	    // client username
			 "a nonce",	    // client nonce
			 "somepassword",    // client password
			 PJ_FALSE,	    // client dummy MI
			 PJ_TRUE,	    // expected error
			 PJ_STATUS_FROM_STUN_CODE(401), // expected code
			 REALM,		    // expected realm
			 NONCE,		    // expected nonce
			 &long_term_check1  // more check
			 );
    if (rc != 0) {
	goto done;
    }

    /* Successful long term authentication */
    rc = run_client_test("Successful scenario (long term)",  // title
			 PJ_TRUE,	    // server responding
			 PJ_STUN_AUTH_LONG_TERM, // server auth
			 PJ_STUN_AUTH_LONG_TERM, // client auth
			 REALM,		    // client realm
			 USERNAME,	    // client username
			 "anothernonce",    // client nonce
			 PASSWORD,	    // client password
			 PJ_FALSE,	    // client dummy MI
			 PJ_FALSE,	    // expected error
			 0,		    // expected code
			 NULL,		    // expected realm
			 NULL,		    // expected nonce
			 &long_term_check3  // more check
			 );
    if (rc != 0) {
	goto done;
    }

    /*
     * (our own) Extended tests for long term credential
     */

    /* If REALM doesn't match, server must respond with 401
     */
    rc = run_client_test("Invalid REALM (long term)",  // title
			 PJ_TRUE,	    // server responding
			 PJ_STUN_AUTH_LONG_TERM, // server auth
			 PJ_STUN_AUTH_LONG_TERM, // client auth
			 "anotherrealm",    // client realm
			 USERNAME,	    // client username
			 NONCE,		    // client nonce
			 PASSWORD,	    // client password
			 PJ_FALSE,	    // client dummy MI
			 PJ_TRUE,	    // expected error
			 PJ_STATUS_FROM_STUN_CODE(401), // expected code
			 REALM,		    // expected realm
			 NONCE,		    // expected nonce
			 &long_term_check1  // more check
			 );
    if (rc != 0) {
	goto done;
    }

    /* Invalid HMAC */

    /* Valid static short term, without NONCE */

    /* Valid static short term, WITH NONCE */

    /* Valid static long term (with NONCE */

    /* Valid dynamic short term (without NONCE) */

    /* Valid dynamic short term (with NONCE) */

    /* Valid dynamic long term (with NONCE) */


done:
    pj_timer_heap_destroy(stun_cfg.timer_heap);
    pj_pool_release(pool);
    return rc;
}
