Index: pjproject/trunk/pjnath/src/pjnath/stun_session.c
===================================================================
--- pjproject/trunk/pjnath/src/pjnath/stun_session.c	(revision 1080)
+++ pjproject/trunk/pjnath/src/pjnath/stun_session.c	(revision 1089)
@@ -207,12 +207,29 @@
 }
 
-static pj_str_t *get_passwd(pj_stun_session *sess)
-{
-    if (sess->cred == NULL)
+static pj_str_t *get_passwd(pj_stun_session *sess, pj_pool_t *pool,
+			    const pj_stun_msg *msg)
+{
+    if (sess->cred == NULL) {
 	return NULL;
-    else if (sess->cred->type == PJ_STUN_AUTH_CRED_STATIC)
+    } else if (sess->cred->type == PJ_STUN_AUTH_CRED_STATIC) {
 	return &sess->cred->data.static_cred.data;
-    else
+    } else if (sess->cred->type == PJ_STUN_AUTH_CRED_DYNAMIC) {
+	pj_str_t realm, username, nonce;
+	pj_str_t *password;
+	void *user_data = sess->cred->data.dyn_cred.user_data;
+	int data_type = 0;
+	pj_status_t status;
+
+	realm.slen = username.slen = nonce.slen = 0;
+	password = PJ_POOL_ZALLOC_T(pool, pj_str_t);
+	status = (*sess->cred->data.dyn_cred.get_cred)(msg, user_data, pool,
+						       &realm, &username,
+						       &nonce, &data_type,
+						       password);
+	return password;
+
+    } else {
 	return NULL;
+    }
 }
 
@@ -222,4 +239,8 @@
 {
     pj_status_t status = 0;
+    pj_str_t realm, username, nonce, password;
+    int data_type = 0;
+
+    realm.slen = username.slen = nonce.slen = password.slen = 0;
 
     /* The server SHOULD include a SERVER attribute in all responses */
@@ -239,26 +260,49 @@
 	!PJ_STUN_IS_ERROR_RESPONSE(msg->hdr.type)) 
     {
-	const pj_str_t *username;
-
-	/* Create and add USERNAME attribute */
-	username = &sess->cred->data.static_cred.username;
+	realm = sess->cred->data.static_cred.realm;
+	username = sess->cred->data.static_cred.username;
+	data_type = sess->cred->data.static_cred.data_type;
+	password = sess->cred->data.static_cred.data;
+	nonce = sess->cred->data.static_cred.nonce;
+
+    } else if (sess->cred && sess->cred->type == PJ_STUN_AUTH_CRED_DYNAMIC &&
+	       !PJ_STUN_IS_ERROR_RESPONSE(msg->hdr.type)) 
+    {
+	void *user_data = sess->cred->data.dyn_cred.user_data;
+
+	status = (*sess->cred->data.dyn_cred.get_cred)(msg, user_data, pool,
+						       &realm, &username,
+						       &nonce, &data_type,
+						       &password);
+	if (status != PJ_SUCCESS)
+	    return status;
+    }
+
+
+    /* Create and add USERNAME attribute */
+    status = pj_stun_msg_add_string_attr(pool, msg,
+					 PJ_STUN_ATTR_USERNAME,
+					 &username);
+    PJ_ASSERT_RETURN(status==PJ_SUCCESS, status);
+
+    /* Add REALM only when long term credential is used */
+    if (realm.slen) {
 	status = pj_stun_msg_add_string_attr(pool, msg,
-					     PJ_STUN_ATTR_USERNAME,
-					     username);
+					    PJ_STUN_ATTR_REALM,
+					    &realm);
 	PJ_ASSERT_RETURN(status==PJ_SUCCESS, status);
-
-	/* Add REALM only when long term credential is used */
-	if (sess->cred->data.static_cred.realm.slen) {
-	    const pj_str_t *realm = &sess->cred->data.static_cred.realm;
-	    status = pj_stun_msg_add_string_attr(pool, msg,
-						PJ_STUN_ATTR_REALM,
-						realm);
-	}
-
-	/* Add MESSAGE-INTEGRITY attribute */
-	status = pj_stun_msg_add_msgint_attr(pool, msg);
-	PJ_ASSERT_RETURN(status==PJ_SUCCESS, status);
-
-    } 
+    }
+
+    /* Add NONCE when desired */
+    if (nonce.slen) {
+	status = pj_stun_msg_add_string_attr(pool, msg,
+					    PJ_STUN_ATTR_NONCE,
+					    &nonce);
+    }
+
+    /* Add MESSAGE-INTEGRITY attribute */
+    status = pj_stun_msg_add_msgint_attr(pool, msg);
+    PJ_ASSERT_RETURN(status==PJ_SUCCESS, status);
+
 
     /* Add FINGERPRINT attribute if necessary */
@@ -543,5 +587,6 @@
     /* Encode message */
     status = pj_stun_msg_encode(tdata->msg, tdata->pkt, tdata->max_len,
-			        0, get_passwd(sess), &tdata->pkt_size);
+			        0, get_passwd(sess, tdata->pool, tdata->msg),
+				&tdata->pkt_size);
     if (status != PJ_SUCCESS) {
 	pj_stun_msg_destroy_tdata(sess, tdata);
@@ -640,16 +685,19 @@
     pj_status_t status;
 
+    /* Apply options */
+    if (!retransmission) {
+	status = apply_msg_options(sess, pool, response);
+	if (status != PJ_SUCCESS)
+	    return status;
+    }
+
     /* Alloc packet buffer */
     out_max_len = PJ_STUN_MAX_PKT_LEN;
     out_pkt = pj_pool_alloc(pool, out_max_len);
 
-    /* Apply options */
-    if (!retransmission) {
-	apply_msg_options(sess, pool, response);
-    }
-
     /* Encode */
     status = pj_stun_msg_encode(response, out_pkt, out_max_len, 0, 
-				get_passwd(sess), &out_len);
+				get_passwd(sess, pool, response),
+				&out_len);
     if (status != PJ_SUCCESS) {
 	LOG_ERR_(sess, "Error encoding message", status);
