belle_sip_register_tester.c 43.4 KB
Newer Older
Simon Morlat's avatar
Simon Morlat committed
1 2
/*
	belle-sip - SIP (RFC3261) library.
3
	Copyright (C) 2010  Belledonne Communications SARL
Simon Morlat's avatar
Simon Morlat committed
4

5 6 7 8
	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.
Simon Morlat's avatar
Simon Morlat committed
9

10 11 12 13
	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.
Simon Morlat's avatar
Simon Morlat committed
14

15 16
	You should have received a copy of the GNU General Public License
	along with this program.  If not, see <http://www.gnu.org/licenses/>.
Simon Morlat's avatar
Simon Morlat committed
17 18 19
*/

#include "belle-sip/belle-sip.h"
20
#include "belle_sip_internal.h"
Ghislain MARY's avatar
Ghislain MARY committed
21
#include "belle_sip_tester.h"
22

Simon Morlat's avatar
Simon Morlat committed
23 24
#include "register_tester.h"

Ghislain MARY's avatar
Ghislain MARY committed
25

26
const char *test_domain="sip2.linphone.org";
27
const char *auth_domain="sip.linphone.org";
jehan's avatar
jehan committed
28
const char *client_auth_domain="client.example.org";
Simon Morlat's avatar
Simon Morlat committed
29
const char *client_auth_outbound_proxy="sips:sip2.linphone.org:5063";
30
const char *no_server_running_here="sip:test.linphone.org:3;transport=tcp";
31
const char *no_response_here="sip:78.220.48.77:3;transport=%s";
32
const char *test_domain_tls_to_tcp="sip:sip2.linphone.org:5060;transport=tls";
33
const char *test_http_proxy_addr="sip.linphone.org";
34
const char *test_with_wrong_cname="sips:rototo.com;maddr=91.121.209.194";
35
int test_http_proxy_port = 3128 ;
jehan's avatar
jehan committed
36

jehan's avatar
jehan committed
37
static int is_register_ok;
38
static int number_of_challenge;
39
static int using_transaction;
40 41
static int io_error_count=0;

jehan's avatar
jehan committed
42 43 44
belle_sip_stack_t * stack;
belle_sip_provider_t *prov;
static belle_sip_listener_t* l;
Ghislain MARY's avatar
Ghislain MARY committed
45 46 47 48
belle_sip_request_t* authorized_request;
belle_sip_listener_callbacks_t listener_callbacks;
belle_sip_listener_t *listener;

jehan's avatar
jehan committed
49

50
static void process_dialog_terminated(void *user_ctx, const belle_sip_dialog_terminated_event_t *event){
51 52
	BELLESIP_UNUSED(user_ctx);
	BELLESIP_UNUSED(event);
53 54
	belle_sip_message("process_dialog_terminated called");
}
Ghislain MARY's avatar
Ghislain MARY committed
55

56
static void process_io_error(void *user_ctx, const belle_sip_io_error_event_t *event){
57 58
	BELLESIP_UNUSED(user_ctx);
	BELLESIP_UNUSED(event);
59
	belle_sip_message("process_io_error, exiting main loop");
60
	belle_sip_main_loop_quit(belle_sip_stack_get_main_loop(stack));
61
	io_error_count++;
62
	/*BC_ASSERT(CU_FALSE);*/
63
}
Ghislain MARY's avatar
Ghislain MARY committed
64

65
static void process_request_event(void *user_ctx, const belle_sip_request_event_t *event){
66 67
	BELLESIP_UNUSED(user_ctx);
	BELLESIP_UNUSED(event);
68 69
	belle_sip_message("process_request_event");
}
Ghislain MARY's avatar
Ghislain MARY committed
70

71
static void process_response_event(void *user_ctx, const belle_sip_response_event_t *event){
72 73
	int status;
	belle_sip_request_t* request;
74
	BELLESIP_UNUSED(user_ctx);
75 76 77
	if (!BC_ASSERT_PTR_NOT_NULL(belle_sip_response_event_get_response(event))) {
		return;
	}
78 79 80
	belle_sip_message("process_response_event [%i] [%s]"
					,status=belle_sip_response_get_status_code(belle_sip_response_event_get_response(event))
					,belle_sip_response_get_reason_phrase(belle_sip_response_event_get_response(event)));
81 82 83


	if (status==401){
84 85
		belle_sip_header_cseq_t* cseq;
		belle_sip_client_transaction_t *t;
86
		belle_sip_uri_t *dest;
87 88
		// BC_ASSERT_NOT_EQUAL(number_of_challenge,2);
		BC_ASSERT_PTR_NOT_NULL(belle_sip_response_event_get_client_transaction(event)); /*require transaction mode*/
89
		dest=belle_sip_client_transaction_get_route(belle_sip_response_event_get_client_transaction(event));
90
		request=belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(belle_sip_response_event_get_client_transaction(event)));
91
		cseq=(belle_sip_header_cseq_t*)belle_sip_message_get_header(BELLE_SIP_MESSAGE(request),BELLE_SIP_CSEQ);
92
		belle_sip_header_cseq_set_seq_number(cseq,belle_sip_header_cseq_get_seq_number(cseq)+1);
93 94
		belle_sip_message_remove_header(BELLE_SIP_MESSAGE(request),BELLE_SIP_AUTHORIZATION);
		belle_sip_message_remove_header(BELLE_SIP_MESSAGE(request),BELLE_SIP_PROXY_AUTHORIZATION);
95
		BC_ASSERT_TRUE(belle_sip_provider_add_authorization(prov,request,belle_sip_response_event_get_response(event),NULL,NULL,auth_domain));
96

97
		t=belle_sip_provider_create_client_transaction(prov,request);
98
		belle_sip_client_transaction_send_request_to(t,dest);
99
		number_of_challenge++;
100
		authorized_request=request;
101
		belle_sip_object_ref(authorized_request);
102
	}  else {
103
		BC_ASSERT_EQUAL(status,200,int,"%d");
104 105 106 107
		is_register_ok=1;
		using_transaction=belle_sip_response_event_get_client_transaction(event)!=NULL;
		belle_sip_main_loop_quit(belle_sip_stack_get_main_loop(stack));
	}
108
}
Ghislain MARY's avatar
Ghislain MARY committed
109

110
static void process_timeout(void *user_ctx, const belle_sip_timeout_event_t *event){
111 112
	BELLESIP_UNUSED(user_ctx);
	BELLESIP_UNUSED(event);
113 114
	belle_sip_message("process_timeout");
}
Ghislain MARY's avatar
Ghislain MARY committed
115

116
static void process_transaction_terminated(void *user_ctx, const belle_sip_transaction_terminated_event_t *event){
117 118
	BELLESIP_UNUSED(user_ctx);
	BELLESIP_UNUSED(event);
119 120
	belle_sip_message("process_transaction_terminated");
}
Ghislain MARY's avatar
Ghislain MARY committed
121

Simon Morlat's avatar
Simon Morlat committed
122
const char* belle_sip_tester_client_cert = /*for URI:sip:tester@client.example.org*/
jehan's avatar
jehan committed
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
		"-----BEGIN CERTIFICATE-----\n"
		"MIIDYzCCAsygAwIBAgIBCDANBgkqhkiG9w0BAQUFADCBuzELMAkGA1UEBhMCRlIx\n"
		"EzARBgNVBAgMClNvbWUtU3RhdGUxETAPBgNVBAcMCEdyZW5vYmxlMSIwIAYDVQQK\n"
		"DBlCZWxsZWRvbm5lIENvbW11bmljYXRpb25zMQwwCgYDVQQLDANMQUIxFjAUBgNV\n"
		"BAMMDUplaGFuIE1vbm5pZXIxOjA4BgkqhkiG9w0BCQEWK2plaGFuLm1vbm5pZXJA\n"
		"YmVsbGVkb25uZS1jb21tdW5pY2F0aW9ucy5jb20wHhcNMTMxMDAzMTQ0MTEwWhcN\n"
		"MjMxMDAxMTQ0MTEwWjCBtTELMAkGA1UEBhMCRlIxDzANBgNVBAgMBkZyYW5jZTER\n"
		"MA8GA1UEBwwIR3Jlbm9ibGUxIjAgBgNVBAoMGUJlbGxlZG9ubmUgQ29tbXVuaWNh\n"
		"dGlvbnMxDDAKBgNVBAsMA0xBQjEUMBIGA1UEAwwLY2xpZW50IGNlcnQxOjA4Bgkq\n"
		"hkiG9w0BCQEWK2plaGFuLm1vbm5pZXJAYmVsbGVkb25uZS1jb21tdW5pY2F0aW9u\n"
		"cy5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALZxC/qBi/zB/4lgI7V7\n"
		"I5TsmMmOp0+R/TCyVnYvKQuaJXh9i+CobVM7wj/pQg8RgsY1x+4mVwH1QbhOdIN0\n"
		"ExYHKgLTPlo9FaN6oHPOcHxU/wt552aZhCHC+ushwUUyjy8+T09UOP+xK9V7y5uD\n"
		"ZY+vIOvi6QNwc5cqyy8TREwNAgMBAAGjezB5MAkGA1UdEwQCMAAwLAYJYIZIAYb4\n"
		"QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQWBBTL\n"
		"eWEg7jewRbQbKXSdBvsyygGIFzAfBgNVHSMEGDAWgBQGX13HFq9i+C1ucQOIoNYd\n"
		"KwR/ujANBgkqhkiG9w0BAQUFAAOBgQBTbEoi94pVfevbK22Oj8PJFsuy+el1pJG+\n"
		"h0XGM9SQGfbcS7PsV/MhFXtmpnmj3vQB3u5QtMGtWcLA2uxXi79i82gw+oEpBKHR\n"
		"sLqsNCzWNCL9n1pjpNSdqqBFGUdB9pSpnYalujAbuzkqq1ZLyzsElvK7pCaLQcSs\n"
		"oEncRDdPOA==\n"
		"-----END CERTIFICATE-----";

145 146 147
/* fingerprint of certificate generated using openssl x509 -fingerprint */
const char* belle_sip_tester_client_cert_fingerprint =
		"SHA-1 79:2F:9E:8B:28:CC:38:53:90:1D:71:DC:8F:70:66:75:E5:34:CE:C4";
jehan's avatar
jehan committed
148

Simon Morlat's avatar
Simon Morlat committed
149
const char* belle_sip_tester_private_key =
jehan's avatar
jehan committed
150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167
		"-----BEGIN ENCRYPTED PRIVATE KEY-----\n"
		"MIICxjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIbEHnQwhgRwoCAggA\n"
		"MBQGCCqGSIb3DQMHBAgmrtCEBCP9kASCAoCq9EKInROalaBSLWY44U4RVAC+CKdx\n"
		"Q8ooT7Bz/grgZuCiaGf0UKINJeV4LYHoP+AWjCH8EeebIA8dldNy5rGcBTt7sXd1\n"
		"QOGmnkBplXTW/NTsb9maYRK56kNJhLE4DR5X5keziV1Tdy2KBmTlpllsCXWsSOBq\n"
		"iI63PTaakIvZxA0TEmie5QQWpH777e/LmW3vVHdH8hhp2zeDDjfSW2E290+ce4Yj\n"
		"SDW9oFXvauzhzhSYRkUdfoJSbpu5MYwyzhjAXQpmBJDauu7+jAU/rQw6TLmYjDNZ\n"
		"3PYHzyD4N7tCG9u4mPBo33dhUirP+8E1BftHB+i/VIn6pI3ypMyiFZ1ZCHqi4vhW\n"
		"z7aChRrUY/8XWCpln3azcfj4SW+Mz62sAChY8rn+yyxFgIno8d9rrx67jyAnYJ6Q\n"
		"sfIMwKp3Sz5oI7IDk8If5SuBVkpqlRV+eZFT6zRRFk65beYpq70BN2mYaKzSV8A7\n"
		"rnciho/dfa9wvyWmkqXciBgWh18UTACOM9HPLmQef3FGaUDLiTAGS1osyypGUEPt\n"
		"Ox3u51qpYkibwyQZo1+ujQkh9PiKfevIAXmty0nTFWMEED15G2SJKjunw5N1rEAh\n"
		"M9jlYpLnATcfigPfGo19QrIPQ1c0LB4BqdwAWN3ZLe0QqYdgwzdcwIoLQRp9iDcw\n"
		"Omc31+38cTc2yGQ2Y2XHZkL8GY/rkqkbhVt9Rnh+VJxFeB6FlsL66EycApe07ngx\n"
		"QimGP57yp4aBzpJyW+6GPf8A/Ogsv3ay1QBLUiGEJtUglRHnl9F6nm5Nxm7wubVx\n"
		"WEuSefVM4xgB+mfQauAJu2N9yKhzXOytslZflpa06qJedlLYFk9njvcv\n"
		"-----END ENCRYPTED PRIVATE KEY-----\n";

Simon Morlat's avatar
Simon Morlat committed
168
const char* belle_sip_tester_private_key_passwd="secret";
jehan's avatar
jehan committed
169 170


171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216
const char *belle_sip_tester_root_ca = 
"-----BEGIN CERTIFICATE-----\n"
"MIIDRjCCAq+gAwIBAgIJAJ3nFcA7qFrOMA0GCSqGSIb3DQEBBQUAMIG7MQswCQYD\n"
"VQQGEwJGUjETMBEGA1UECAwKU29tZS1TdGF0ZTERMA8GA1UEBwwIR3Jlbm9ibGUx\n"
"IjAgBgNVBAoMGUJlbGxlZG9ubmUgQ29tbXVuaWNhdGlvbnMxDDAKBgNVBAsMA0xB\n"
"QjEWMBQGA1UEAwwNSmVoYW4gTW9ubmllcjE6MDgGCSqGSIb3DQEJARYramVoYW4u\n"
"bW9ubmllckBiZWxsZWRvbm5lLWNvbW11bmljYXRpb25zLmNvbTAeFw0xMzA0MzAx\n"
"MzMwMThaFw0yMzA0MjgxMzMwMThaMIG7MQswCQYDVQQGEwJGUjETMBEGA1UECAwK\n"
"U29tZS1TdGF0ZTERMA8GA1UEBwwIR3Jlbm9ibGUxIjAgBgNVBAoMGUJlbGxlZG9u\n"
"bmUgQ29tbXVuaWNhdGlvbnMxDDAKBgNVBAsMA0xBQjEWMBQGA1UEAwwNSmVoYW4g\n"
"TW9ubmllcjE6MDgGCSqGSIb3DQEJARYramVoYW4ubW9ubmllckBiZWxsZWRvbm5l\n"
"LWNvbW11bmljYXRpb25zLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA\n"
"z5F8mMh3SUr6NUd7tq2uW2Kdn22Zn3kNpLYb78AQK4IoQMOLGXbBdyoXvz1fublg\n"
"bxtLYsiGhICd7Ul9zLGc3edn85LbD3Skb7ERx6MakRnYep3FzagZJhn14QEaZCx6\n"
"3Qs0Ir4rSP7hmlpYt8VO/zqqNR3tsA59O0D9c7bpQ7UCAwEAAaNQME4wHQYDVR0O\n"
"BBYEFAZfXccWr2L4LW5xA4ig1h0rBH+6MB8GA1UdIwQYMBaAFAZfXccWr2L4LW5x\n"
"A4ig1h0rBH+6MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEAKvmt2m1o\n"
"axGKc0DjiJPypU/NsAf4Yu0nOnY8pHqJJCB0AWVoAPM7vGYPWpeH7LSdGZLuT9eK\n"
"FUWGJhPnkrnklmBdVB0l7qXYjR5uf766HDkoDxuLhNifow3IYvsS+L2Y6puRQb9w\n"
"HLMDE29mBDl0WyoX3h0yR0EiAO15V9A7I10=\n"
"-----END CERTIFICATE-----\n"
"\n"
"AddTrust External Root used for *.linphone.org\n"
"======================\n"
"-----BEGIN CERTIFICATE-----\n"
"MIIENjCCAx6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJTRTEUMBIGA1UEChML\n"
"QWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4dGVybmFsIFRUUCBOZXR3b3JrMSIwIAYD\n"
"VQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEw\n"
"NDgzOFowbzELMAkGA1UEBhMCU0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMSYwJAYDVQQLEx1BZGRU\n"
"cnVzdCBFeHRlcm5hbCBUVFAgTmV0d29yazEiMCAGA1UEAxMZQWRkVHJ1c3QgRXh0ZXJuYWwgQ0Eg\n"
"Um9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALf3GjPm8gAELTngTlvtH7xsD821\n"
"+iO2zt6bETOXpClMfZOfvUq8k+0DGuOPz+VtUFrWlymUWoCwSXrbLpX9uMq/NzgtHj6RQa1wVsfw\n"
"Tz/oMp50ysiQVOnGXw94nZpAPA6sYapeFI+eh6FqUNzXmk6vBbOmcZSccbNQYArHE504B4YCqOmo\n"
"aSYYkKtMsE8jqzpPhNjfzp/haW+710LXa0Tkx63ubUFfclpxCDezeWWkWaCUN/cALw3CknLa0Dhy\n"
"2xSoRcRdKn23tNbE7qzNE0S3ySvdQwAl+mG5aWpYIxG3pzOPVnVZ9c0p10a3CitlttNCbxWyuHv7\n"
"7+ldU9U0WicCAwEAAaOB3DCB2TAdBgNVHQ4EFgQUrb2YejS0Jvf6xCZU7wO94CTLVBowCwYDVR0P\n"
"BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIwSBkTCBjoAUrb2YejS0Jvf6xCZU7wO94CTL\n"
"VBqhc6RxMG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRUcnVzdCBBQjEmMCQGA1UECxMdQWRk\n"
"VHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsxIjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENB\n"
"IFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBALCb4IUlwtYj4g+WBpKdQZic2YR5gdkeWxQHIzZl\n"
"j7DYd7usQWxHYINRsPkyPef89iYTx4AWpb9a/IfPeHmJIZriTAcKhjW88t5RxNKWt9x+Tu5w/Rw5\n"
"6wwCURQtjr0W4MHfRnXnJK3s9EK0hZNwEGe6nQY1ShjTK3rMUUKhemPR5ruhxSvCNr4TDea9Y355\n"
"e6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEXc4g/VhsxOBi0cQ+azcgOno4u\n"
"G+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5amnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ=\n"
"-----END CERTIFICATE-----\n";

217
static void process_auth_requested(void *user_ctx, belle_sip_auth_event_t *event){
218
	BELLESIP_UNUSED(user_ctx);
219
	if (belle_sip_auth_event_get_mode(event) == BELLE_SIP_AUTH_MODE_HTTP_DIGEST) {
220 221
		const char *username = belle_sip_auth_event_get_username(event);
		const char *realm = belle_sip_auth_event_get_realm(event);
jehan's avatar
jehan committed
222
		belle_sip_message("process_auth_requested requested for [%s@%s]"
223 224
				,username?username:""
				,realm?realm:"");
jehan's avatar
jehan committed
225 226
		belle_sip_auth_event_set_passwd(event,"secret");
	} else if (belle_sip_auth_event_get_mode(event) == BELLE_SIP_AUTH_MODE_TLS) {
227
		const char *distinguished_name = NULL;
Simon Morlat's avatar
Simon Morlat committed
228 229
		belle_sip_certificates_chain_t* cert = belle_sip_certificates_chain_parse(belle_sip_tester_client_cert,strlen(belle_sip_tester_client_cert),BELLE_SIP_CERTIFICATE_RAW_FORMAT_PEM);
		belle_sip_signing_key_t* key = belle_sip_signing_key_parse(belle_sip_tester_private_key,strlen(belle_sip_tester_private_key),belle_sip_tester_private_key_passwd);
jehan's avatar
jehan committed
230 231
		belle_sip_auth_event_set_client_certificates_chain(event,cert);
		belle_sip_auth_event_set_signing_key(event,key);
232 233
		distinguished_name = belle_sip_auth_event_get_distinguished_name(event);
		belle_sip_message("process_auth_requested requested for  DN[%s]",distinguished_name?distinguished_name:"");
jehan's avatar
jehan committed
234 235 236 237

	} else {
		belle_sip_error("Unexpected auth mode");
	}
238
}
239

240
int register_before_all(void) {
241
	belle_sip_listening_point_t *lp;
jehan's avatar
jehan committed
242
	stack=belle_sip_stack_new(NULL);
243
	lp=belle_sip_stack_create_listening_point(stack,"0.0.0.0",7060,"UDP");
244
	prov=belle_sip_stack_create_provider(stack,lp);
245

246 247
	lp=belle_sip_stack_create_listening_point(stack,"0.0.0.0",7060,"TCP");
	belle_sip_provider_add_listening_point(prov,lp);
248
	lp=belle_sip_stack_create_listening_point(stack,"0.0.0.0",7061,"TLS");
jehan's avatar
jehan committed
249
	if (lp) {
250
		belle_tls_crypto_config_t *crypto_config=belle_tls_crypto_config_new();
251 252
	
		belle_tls_crypto_config_set_root_ca_data(crypto_config, belle_sip_tester_root_ca);
253
		belle_sip_tls_listening_point_set_crypto_config(BELLE_SIP_TLS_LISTENING_POINT(lp), crypto_config);
jehan's avatar
jehan committed
254
		belle_sip_provider_add_listening_point(prov,lp);
jehan's avatar
jehan committed
255
		belle_sip_object_unref(crypto_config);
jehan's avatar
jehan committed
256
	}
jehan's avatar
jehan committed
257

258 259 260 261 262 263 264 265 266
	listener_callbacks.process_dialog_terminated=process_dialog_terminated;
	listener_callbacks.process_io_error=process_io_error;
	listener_callbacks.process_request_event=process_request_event;
	listener_callbacks.process_response_event=process_response_event;
	listener_callbacks.process_timeout=process_timeout;
	listener_callbacks.process_transaction_terminated=process_transaction_terminated;
	listener_callbacks.process_auth_requested=process_auth_requested;
	listener_callbacks.listener_destroyed=NULL;
	listener=belle_sip_listener_create_from_callbacks(&listener_callbacks,NULL);
jehan's avatar
jehan committed
267 268
	return 0;
}
Ghislain MARY's avatar
Ghislain MARY committed
269

270
int register_after_all(void) {
271
	belle_sip_object_unref(prov);
jehan's avatar
jehan committed
272
	belle_sip_object_unref(stack);
273
	belle_sip_object_unref(listener);
jehan's avatar
jehan committed
274 275
	return 0;
}
jehan's avatar
jehan committed
276 277 278 279 280 281

void unregister_user(belle_sip_stack_t * stack
					,belle_sip_provider_t *prov
					,belle_sip_request_t* initial_request
					,int use_transaction) {
	belle_sip_request_t *req;
282 283 284
	belle_sip_header_cseq_t* cseq;
	belle_sip_header_expires_t* expires_header;
	int i;
jehan's avatar
jehan committed
285 286 287 288
	belle_sip_provider_add_sip_listener(prov,l);
	is_register_ok=0;
	using_transaction=0;
	req=(belle_sip_request_t*)belle_sip_object_clone((belle_sip_object_t*)initial_request);
289
	belle_sip_object_ref(req);
290
	cseq=(belle_sip_header_cseq_t*)belle_sip_message_get_header((belle_sip_message_t*)req,BELLE_SIP_CSEQ);
jehan's avatar
jehan committed
291
	belle_sip_header_cseq_set_seq_number(cseq,belle_sip_header_cseq_get_seq_number(cseq)+2); /*+2 if initial reg was challenged*/
292
	expires_header=(belle_sip_header_expires_t*)belle_sip_message_get_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_EXPIRES);
jehan's avatar
jehan committed
293 294
	belle_sip_header_expires_set_expires(expires_header,0);
	if (use_transaction){
295
		belle_sip_client_transaction_t *t;
296
		belle_sip_provider_add_authorization(prov,req,NULL,NULL,NULL,NULL); /*just in case*/
297
		t=belle_sip_provider_create_client_transaction(prov,req);
jehan's avatar
jehan committed
298 299
		belle_sip_client_transaction_send_request(t);
	}else belle_sip_provider_send_request(prov,req);
300 301 302 303 304 305 306 307
	for(i=0;!is_register_ok && i<20 ;i++) {
		belle_sip_stack_sleep(stack,500);
		if (!use_transaction && !is_register_ok) {
			belle_sip_object_ref(req);
			belle_sip_provider_send_request(prov,req); /*manage retransmitions*/
		}
	}

308 309
	BC_ASSERT_EQUAL(is_register_ok,1,int,"%d");
	BC_ASSERT_EQUAL(using_transaction,use_transaction,int,"%d");
310
	belle_sip_object_unref(req);
jehan's avatar
jehan committed
311 312
	belle_sip_provider_remove_sip_listener(prov,l);
}
Ghislain MARY's avatar
Ghislain MARY committed
313

jehan's avatar
jehan committed
314
belle_sip_request_t* try_register_user_at_domain(belle_sip_stack_t * stack
315 316 317 318 319 320 321
	,belle_sip_provider_t *prov
	,const char *transport
	,int use_transaction
	,const char* username
	,const char* domain
	,const char* outbound_proxy
	,int success_expected) {
322
	belle_sip_request_t *req,*copy;
323 324
	char identity[256];
	char uri[256];
325
	int i;
Simon Morlat's avatar
Simon Morlat committed
326
	char *outbound=NULL;
327
	int do_manual_retransmissions = FALSE;
328

329
	number_of_challenge=0;
330
	if (transport)
331 332
		snprintf(uri,sizeof(uri),"sip:%s;transport=%s",domain,transport);
	else snprintf(uri,sizeof(uri),"sip:%s",domain);
jehan's avatar
jehan committed
333

Simon Morlat's avatar
Simon Morlat committed
334 335
	if (transport && strcasecmp("tls",transport)==0 && belle_sip_provider_get_listening_point(prov,"tls")==NULL){
		belle_sip_error("No TLS support, test skipped.");
jehan's avatar
jehan committed
336
		return NULL;
Simon Morlat's avatar
Simon Morlat committed
337
	}
338

Simon Morlat's avatar
Simon Morlat committed
339
	if (outbound_proxy){
jehan's avatar
jehan committed
340
		if (strstr(outbound_proxy,"sip:")==NULL && strstr(outbound_proxy,"sips:")==NULL){
Simon Morlat's avatar
Simon Morlat committed
341 342 343
			outbound=belle_sip_strdup_printf("sip:%s",outbound_proxy);
		}else outbound=belle_sip_strdup(outbound_proxy);
	}
Simon Morlat's avatar
Simon Morlat committed
344

345
	snprintf(identity,sizeof(identity),"Tester <sip:%s@%s>",username,domain);
Simon Morlat's avatar
Simon Morlat committed
346
	req=belle_sip_request_create(
347 348 349 350 351 352 353 354
						belle_sip_uri_parse(uri),
						"REGISTER",
						belle_sip_provider_create_call_id(prov),
						belle_sip_header_cseq_create(20,"REGISTER"),
						belle_sip_header_from_create2(identity,BELLE_SIP_RANDOM_TAG),
						belle_sip_header_to_create2(identity,NULL),
						belle_sip_header_via_new(),
						70);
355
	belle_sip_object_ref(req);
jehan's avatar
jehan committed
356
	is_register_ok=0;
357
	io_error_count=0;
358
	using_transaction=0;
jehan's avatar
jehan committed
359
	belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(belle_sip_header_expires_create(600)));
360
	belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(belle_sip_header_contact_new()));
361
	copy=(belle_sip_request_t*)belle_sip_object_ref(belle_sip_object_clone((belle_sip_object_t*)req));
jehan's avatar
jehan committed
362
	belle_sip_provider_add_sip_listener(prov,l=BELLE_SIP_LISTENER(listener));
363 364
	if (use_transaction){
		belle_sip_client_transaction_t *t=belle_sip_provider_create_client_transaction(prov,req);
Simon Morlat's avatar
Simon Morlat committed
365
		belle_sip_client_transaction_send_request_to(t,outbound?belle_sip_uri_parse(outbound):NULL);
366 367
	}else{
		belle_sip_provider_send_request(prov,req);
368
		do_manual_retransmissions = (transport == NULL) || (strcasecmp(transport,"udp") == 0);
369
	}
370 371
	for(i=0;!is_register_ok && i<20 && io_error_count==0;i++) {
		belle_sip_stack_sleep(stack,500);
372
		if (do_manual_retransmissions && !is_register_ok) {
373 374 375 376
			belle_sip_object_ref(req);
			belle_sip_provider_send_request(prov,req); /*manage retransmitions*/
		}
	}
377 378
	BC_ASSERT_EQUAL(is_register_ok,success_expected,int,"%d");
	if (success_expected) BC_ASSERT_EQUAL(using_transaction,use_transaction,int,"%d");
379

380
	belle_sip_object_unref(req);
jehan's avatar
jehan committed
381
	belle_sip_provider_remove_sip_listener(prov,l);
Simon Morlat's avatar
Simon Morlat committed
382
	if (outbound) belle_sip_free(outbound);
383
	return copy;
Simon Morlat's avatar
Simon Morlat committed
384
}
Ghislain MARY's avatar
Ghislain MARY committed
385

jehan's avatar
jehan committed
386 387 388 389 390
belle_sip_request_t* register_user_at_domain(belle_sip_stack_t * stack
					,belle_sip_provider_t *prov
					,const char *transport
					,int use_transaction
					,const char* username
391
					,const char* domain
Simon Morlat's avatar
Simon Morlat committed
392 393
					,const char* outbound) {
	return try_register_user_at_domain(stack,prov,transport,use_transaction,username,domain,outbound,1);
394

jehan's avatar
jehan committed
395
}
Ghislain MARY's avatar
Ghislain MARY committed
396

397 398 399 400
belle_sip_request_t* register_user(belle_sip_stack_t * stack
					,belle_sip_provider_t *prov
					,const char *transport
					,int use_transaction
401
					,const char* username
Simon Morlat's avatar
Simon Morlat committed
402 403
					,const char* outbound) {
	return register_user_at_domain(stack,prov,transport,use_transaction,username,test_domain,outbound);
404
}
405

Simon Morlat's avatar
Simon Morlat committed
406
static void register_with_outbound(const char *transport, int use_transaction,const char* outbound ) {
jehan's avatar
jehan committed
407
	belle_sip_request_t *req;
408

Simon Morlat's avatar
Simon Morlat committed
409
	req=register_user(stack, prov, transport,use_transaction,"tester",outbound);
410 411 412 413
	if (req) {
		unregister_user(stack,prov,req,use_transaction);
		belle_sip_object_unref(req);
	}
jehan's avatar
jehan committed
414
}
Ghislain MARY's avatar
Ghislain MARY committed
415

416
static void register_test(const char *transport, int use_transaction) {
Simon Morlat's avatar
Simon Morlat committed
417
	register_with_outbound(transport,use_transaction,NULL);
418
}
Ghislain MARY's avatar
Ghislain MARY committed
419

420 421
static void stateless_register_udp(void){
	register_test(NULL,0);
jehan's avatar
jehan committed
422
}
423

jehan's avatar
jehan committed
424 425 426 427
static void stateless_register_tls(void){
	register_test("tls",0);
}

428 429 430 431 432 433 434
static void stateless_register_tcp(void){
	register_test("tcp",0);
}

static void stateful_register_udp(void){
	register_test(NULL,1);
}
Ghislain MARY's avatar
Ghislain MARY committed
435

436
static void stateful_register_udp_with_keep_alive(void) {
jehan's avatar
jehan committed
437 438 439 440 441
	belle_sip_listening_point_set_keep_alive(belle_sip_provider_get_listening_point(prov,"udp"),200);
	register_test(NULL,1);
	belle_sip_main_loop_sleep(belle_sip_stack_get_main_loop(stack),500);
	belle_sip_listening_point_set_keep_alive(belle_sip_provider_get_listening_point(prov,"udp"),-1);
}
Ghislain MARY's avatar
Ghislain MARY committed
442

Simon Morlat's avatar
Simon Morlat committed
443 444
static void stateful_register_udp_with_outbound_proxy(void){
	register_with_outbound("udp",1,test_domain);
445 446
}

Simon Morlat's avatar
Simon Morlat committed
447
static void stateful_register_udp_delayed(void){
448
	belle_sip_stack_set_tx_delay(stack,3000);
Simon Morlat's avatar
Simon Morlat committed
449 450 451 452
	register_test(NULL,1);
	belle_sip_stack_set_tx_delay(stack,0);
}

453
static void stateful_register_udp_with_send_error(void){
454
	belle_sip_request_t *req;
455
	belle_sip_stack_set_send_error(stack,-1);
456
	req=try_register_user_at_domain(stack, prov, NULL,1,"tester",test_domain,NULL,0);
457
	belle_sip_stack_set_send_error(stack,0);
458
	if (req) belle_sip_object_unref(req);
459 460
}

461 462
static void stateful_register_tcp(void){
	register_test("tcp",1);
jehan's avatar
jehan committed
463
}
Simon Morlat's avatar
Simon Morlat committed
464

465 466 467
static void stateful_register_tls(void){
	register_test("tls",1);
}
jehan's avatar
jehan committed
468

469 470 471 472 473 474 475
static void stateful_register_tls_with_wrong_cname(void){
	belle_sip_request_t *req;
	
	req = try_register_user_at_domain(stack, prov, "tls", 1, "tester",test_domain, test_with_wrong_cname, 0);
	if (req) belle_sip_object_unref(req);
}

476 477 478 479 480 481
static void stateful_register_tls_with_http_proxy(void) {
	belle_sip_tls_listening_point_t * lp = (belle_sip_tls_listening_point_t*)belle_sip_provider_get_listening_point(prov, "tls");
	if (!lp) {
		belle_sip_error("No TLS support, test skipped.");
		return;
	}
482
	belle_sip_provider_clean_channels(prov);
483 484
	belle_sip_stack_set_http_proxy_host(stack, test_http_proxy_addr);
	belle_sip_stack_set_http_proxy_port(stack, test_http_proxy_port);
485
	register_test("tls",1);
486 487
	belle_sip_stack_set_http_proxy_host(stack, NULL);
	belle_sip_stack_set_http_proxy_port(stack, 0);
488 489 490 491

}

static void stateful_register_tls_with_wrong_http_proxy(void){
492

493 494 495 496 497
	belle_sip_tls_listening_point_t * lp = (belle_sip_tls_listening_point_t*)belle_sip_provider_get_listening_point(prov, "tls");
	if (!lp) {
		belle_sip_error("No TLS support, test skipped.");
		return;
	}
498
	belle_sip_provider_clean_channels(prov);
499 500
	belle_sip_stack_set_http_proxy_host(stack, "mauvaisproxy.linphone.org");
	belle_sip_stack_set_http_proxy_port(stack, test_http_proxy_port);
501
	try_register_user_at_domain(stack,prov,"tls",1,"tester",test_domain,NULL,0);
502 503
	belle_sip_stack_set_http_proxy_host(stack, NULL);
	belle_sip_stack_set_http_proxy_port(stack, 0);
504

505 506 507
}


jehan's avatar
jehan committed
508
static void bad_req_process_io_error(void *user_ctx, const belle_sip_io_error_event_t *event){
509 510
	BELLESIP_UNUSED(user_ctx);
	BELLESIP_UNUSED(event);
jehan's avatar
jehan committed
511 512
	belle_sip_message("bad_req_process_io_error not implemented yet");
}
Ghislain MARY's avatar
Ghislain MARY committed
513

jehan's avatar
jehan committed
514
static void bad_req_process_response_event(void *user_ctx, const belle_sip_response_event_t *event){
515
	belle_sip_response_t *resp=belle_sip_response_event_get_response(event);
jehan's avatar
jehan committed
516 517
	int *bad_request_response_received=(int*)user_ctx;
	if (belle_sip_response_event_get_client_transaction(event) != NULL) {
518 519
		BC_ASSERT_PTR_NOT_NULL(resp);
		BC_ASSERT_EQUAL(belle_sip_response_get_status_code(resp),400,int,"%d");
jehan's avatar
jehan committed
520 521 522
		*bad_request_response_received=1;
		belle_sip_main_loop_quit(belle_sip_stack_get_main_loop(stack));
	}
jehan's avatar
jehan committed
523 524
}

525
static void test_bad_request(void) {
jehan's avatar
jehan committed
526
	belle_sip_request_t *req;
527 528
	belle_sip_listener_t *bad_req_listener;
	belle_sip_client_transaction_t *t;
jehan's avatar
jehan committed
529 530 531 532
	belle_sip_header_address_t* route_address=belle_sip_header_address_create(NULL,belle_sip_uri_create(NULL,test_domain));
	belle_sip_header_route_t* route;
	belle_sip_header_to_t* to = belle_sip_header_to_create2("sip:toto@titi.com",NULL);
	belle_sip_listener_callbacks_t cbs;
533
	belle_sip_listening_point_t *lp=belle_sip_provider_get_listening_point(prov,"TCP");
534
	int bad_request_response_received=0;
jehan's avatar
jehan committed
535 536 537 538
	memset(&cbs,0,sizeof(cbs));

	cbs.process_io_error=bad_req_process_io_error;
	cbs.process_response_event=bad_req_process_response_event;
539

540
	bad_req_listener = belle_sip_listener_create_from_callbacks(&cbs,&bad_request_response_received);
jehan's avatar
jehan committed
541 542

	req=belle_sip_request_create(
543 544 545 546 547 548 549 550
						BELLE_SIP_URI(belle_sip_object_clone(BELLE_SIP_OBJECT(belle_sip_header_address_get_uri(route_address)))),
						"REGISTER",
						belle_sip_provider_create_call_id(prov),
						belle_sip_header_cseq_create(20,"REGISTER"),
						belle_sip_header_from_create2("sip:toto@titi.com",BELLE_SIP_RANDOM_TAG),
						to,
						belle_sip_header_via_new(),
						70);
jehan's avatar
jehan committed
551 552 553 554 555 556 557 558 559

	belle_sip_uri_set_transport_param(belle_sip_header_address_get_uri(route_address),"tcp");
	route = belle_sip_header_route_create(route_address);
	belle_sip_header_set_name(BELLE_SIP_HEADER(to),"BrokenHeader");

	belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(belle_sip_header_expires_create(600)));
	belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(route));
	belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(belle_sip_header_contact_new()));
	belle_sip_provider_add_sip_listener(prov,bad_req_listener);
560
	t=belle_sip_provider_create_client_transaction(prov,req);
jehan's avatar
jehan committed
561
	belle_sip_client_transaction_send_request(t);
562
	belle_sip_stack_sleep(stack,3000);
563
	BC_ASSERT_EQUAL(bad_request_response_received,1,int,"%d");
jehan's avatar
jehan committed
564
	belle_sip_provider_remove_sip_listener(prov,bad_req_listener);
565
	belle_sip_object_unref(bad_req_listener);
566

567
	belle_sip_listening_point_clean_channels(lp);
jehan's avatar
jehan committed
568
}
Simon Morlat's avatar
Simon Morlat committed
569

570

571
static void test_register_authenticate(void) {
572
	belle_sip_request_t *reg;
573
	number_of_challenge=0;
574
	authorized_request=NULL;
575
	reg=register_user_at_domain(stack, prov, "udp",1,"bellesip",auth_domain,NULL);
576 577 578 579 580
	if (authorized_request) {
		unregister_user(stack,prov,authorized_request,1);
		belle_sip_object_unref(authorized_request);
	}
	belle_sip_object_unref(reg);
581
}
jehan's avatar
jehan committed
582

583 584
static void test_register_channel_inactive(void){
	belle_sip_listening_point_t *lp=belle_sip_provider_get_listening_point(prov,"TCP");
585 586 587 588 589 590 591
	BC_ASSERT_PTR_NOT_NULL(lp);
	if (lp) {
		belle_sip_stack_set_inactive_transport_timeout(stack,5);
		belle_sip_listening_point_clean_channels(lp);
		BC_ASSERT_EQUAL(belle_sip_listening_point_get_channel_count(lp),0,int,"%d");
		register_test("tcp",1);
		BC_ASSERT_EQUAL(belle_sip_listening_point_get_channel_count(lp),1,int,"%d");
592 593 594 595 596 597
		belle_sip_stack_sleep(stack, 3000);
		BC_ASSERT_EQUAL(belle_sip_listening_point_get_channel_count(lp),1,int,"%d");
		register_test("tcp",1);
		belle_sip_stack_sleep(stack, 3000);
		BC_ASSERT_EQUAL(belle_sip_listening_point_get_channel_count(lp),1,int,"%d");
		belle_sip_stack_sleep(stack,3000);
598 599 600
		BC_ASSERT_EQUAL(belle_sip_listening_point_get_channel_count(lp),0,int,"%d");
		belle_sip_stack_set_inactive_transport_timeout(stack,3600);
	}
601
}
jehan's avatar
jehan committed
602

603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640
static void test_channel_moving_to_error_and_cleaned(void){
	belle_sip_listening_point_t *lp=belle_sip_provider_get_listening_point(prov,"UDP");
	BC_ASSERT_PTR_NOT_NULL(lp);
	if (lp) {
		belle_sip_request_t *req;
		belle_sip_client_transaction_t *tr;
		char identity[128];
		char uri[128];
		
		belle_sip_listening_point_clean_channels(lp);
		BC_ASSERT_EQUAL(belle_sip_listening_point_get_channel_count(lp),0,int,"%d");
		
		snprintf(identity,sizeof(identity),"Tester <sip:%s@%s>","bellesip",test_domain);
		snprintf(uri,sizeof(uri),"sip:%s",test_domain);
		req = belle_sip_request_create(
						belle_sip_uri_parse(uri),
						"REGISTER",
						belle_sip_provider_create_call_id(prov),
						belle_sip_header_cseq_create(20,"REGISTER"),
						belle_sip_header_from_create2(identity,BELLE_SIP_RANDOM_TAG),
						belle_sip_header_to_create2(identity,NULL),
						belle_sip_header_via_new(),
						70);
		tr = belle_sip_provider_create_client_transaction(prov, req);
		belle_sip_client_transaction_send_request(tr);
		belle_sip_object_ref(tr);
		BC_ASSERT_EQUAL(belle_sip_listening_point_get_channel_count(lp),1,int,"%d");
		/*calling notify_server_error() will make the channel enter the error state, which is what we want to test*/
		belle_sip_channel_notify_server_error((belle_sip_channel_t*)lp->channels->data);
		/*immediately after, we clean the channel from the listening point*/
		belle_sip_listening_point_clean_channels(lp);
		/*we just want to verify that it doesn't crash*/
		belle_sip_stack_sleep(stack, 1000);
		belle_sip_object_unref(tr);
		
	}
}

jehan's avatar
jehan committed
641 642 643 644 645


static void test_register_client_authenticated(void) {
	belle_sip_request_t *reg;
	authorized_request=NULL;
646

Simon Morlat's avatar
Simon Morlat committed
647
	reg=register_user_at_domain(stack, prov, "tls",1,"tester",client_auth_domain,client_auth_outbound_proxy);
jehan's avatar
jehan committed
648 649 650 651
	if (authorized_request) {
		unregister_user(stack,prov,authorized_request,1);
		belle_sip_object_unref(authorized_request);
	}
652
	if (reg) belle_sip_object_unref(reg);
jehan's avatar
jehan committed
653 654
}

655 656 657 658
static void test_connection_failure(void){
	belle_sip_request_t *req;
	io_error_count=0;
	req=try_register_user_at_domain(stack, prov, "TCP",1,"tester","sip.linphone.org",no_server_running_here,0);
659
	BC_ASSERT_GREATER(io_error_count,1,int,"%d");
660 661 662
	if (req) belle_sip_object_unref(req);
}

663
static void test_connection_too_long(const char *transport){
664 665
	belle_sip_request_t *req;
	int orig=belle_sip_stack_get_transport_timeout(stack);
666
	char *no_response_here_with_transport = belle_sip_strdup_printf(no_response_here, transport);
667
	io_error_count=0;
668 669 670 671
	if (transport && strcasecmp("tls",transport)==0 && belle_sip_provider_get_listening_point(prov,"tls")==NULL){
		belle_sip_error("No TLS support, test skipped.");
		return;
	}
672
	belle_sip_stack_set_transport_timeout(stack,2000);
673
	req=try_register_user_at_domain(stack, prov, transport,1,"tester","sip.linphone.org",no_response_here_with_transport,0);
674
	BC_ASSERT_GREATER(io_error_count, 1, int, "%d");
675
	belle_sip_stack_set_transport_timeout(stack,orig);
676
	belle_sip_free(no_response_here_with_transport);
677 678 679
	if (req) belle_sip_object_unref(req);
}

680 681 682 683 684 685 686 687
static void test_connection_too_long_tcp(void){
	test_connection_too_long("tcp");
}

static void test_connection_too_long_tls(void){
	test_connection_too_long("tls");
}

688 689 690
static void test_tls_to_tcp(void){
	belle_sip_request_t *req;
	int orig=belle_sip_stack_get_transport_timeout(stack);
691
	io_error_count=0;
692 693 694
	belle_sip_stack_set_transport_timeout(stack,2000);
	req=try_register_user_at_domain(stack, prov, "TLS",1,"tester",test_domain,test_domain_tls_to_tcp,0);
	if (req){
695
		BC_ASSERT_GREATER(io_error_count,1,int,"%d");
696 697 698 699
		belle_sip_object_unref(req);
	}
	belle_sip_stack_set_transport_timeout(stack,orig);
}
jehan's avatar
jehan committed
700

701
static void register_dns_srv_tcp(void){
702 703 704
	belle_sip_request_t *req;
	io_error_count=0;
	req=try_register_user_at_domain(stack, prov, "TCP",1,"tester",client_auth_domain,"sip:linphone.net;transport=tcp",1);
705
	BC_ASSERT_EQUAL(io_error_count,0,int,"%d");
706 707 708
	if (req) belle_sip_object_unref(req);
}

709 710 711 712 713 714 715 716 717
static void enable_cn_mismatch(int enable){
	belle_sip_listening_point_t *lp =  belle_sip_provider_get_listening_point(prov, "TLS");
	belle_sip_provider_clean_channels(prov);
	if (lp) {
		belle_tls_crypto_config_t *cfg = belle_sip_tls_listening_point_get_crypto_config(BELLE_SIP_TLS_LISTENING_POINT(lp));
		belle_tls_crypto_config_set_verify_exceptions(cfg, enable ? BELLE_TLS_VERIFY_CN_MISMATCH : 0);
	}
}

718 719 720
static void register_dns_srv_tls(void){
	belle_sip_request_t *req;
	io_error_count=0;
721
	enable_cn_mismatch(TRUE);
722
	req=try_register_user_at_domain(stack, prov, "TLS",1,"tester",client_auth_domain,"sip:linphone.net;transport=tls",1);
723
	BC_ASSERT_EQUAL(io_error_count, 0, int, "%d");
724
	if (req) belle_sip_object_unref(req);
725
	enable_cn_mismatch(FALSE);
726 727
}

728 729 730 731 732 733 734 735
static void register_dns_srv_tls_with_http_proxy(void){
	belle_sip_request_t *req;
	belle_sip_tls_listening_point_t * lp = (belle_sip_tls_listening_point_t*)belle_sip_provider_get_listening_point(prov, "tls");
	if (!lp) {
		belle_sip_error("No TLS support, test skipped.");
		return;
	}
	io_error_count=0;
736
	enable_cn_mismatch(TRUE);
737 738
	belle_sip_stack_set_http_proxy_host(stack, test_http_proxy_addr);
	belle_sip_stack_set_http_proxy_port(stack, test_http_proxy_port);
739
	req=try_register_user_at_domain(stack, prov, "TLS",1,"tester",client_auth_domain,"sip:linphone.net;transport=tls",1);
740 741
	belle_sip_stack_set_http_proxy_host(stack, NULL);
	belle_sip_stack_set_http_proxy_port(stack, 0);
742 743
	BC_ASSERT_EQUAL(io_error_count, 0, int, "%d");
	if (req) belle_sip_object_unref(req);
744
	enable_cn_mismatch(FALSE);
745 746
}

747 748 749 750
static void register_dns_load_balancing(void) {
	belle_sip_request_t *req;
	io_error_count = 0;
	req = try_register_user_at_domain(stack, prov, "TCP", 1, "tester", client_auth_domain, "sip:belle-sip.net;transport=tcp", 1);
751
	BC_ASSERT_EQUAL(io_error_count, 0, int, "%d");
752 753 754
	if (req) belle_sip_object_unref(req);
}

755 756 757
static void process_message_response_event(void *user_ctx, const belle_sip_response_event_t *event){
	int status;
	BELLESIP_UNUSED(user_ctx);
758 759 760 761 762 763 764 765 766
	if (BC_ASSERT_PTR_NOT_NULL(belle_sip_response_event_get_response(event))) {
		belle_sip_message("process_response_event [%i] [%s]"
						,status=belle_sip_response_get_status_code(belle_sip_response_event_get_response(event))
						,belle_sip_response_get_reason_phrase(belle_sip_response_event_get_response(event)));

		if (status >= 200){
			is_register_ok=status;
			belle_sip_main_loop_quit(belle_sip_stack_get_main_loop(stack));
		}
767 768
	}
}
jehan's avatar
jehan committed
769
static belle_sip_request_t* send_message_to(belle_sip_request_t *initial_request, const char* realm, belle_sip_uri_t *outbound){
770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795
	int i;
	int io_error_count=0;
	belle_sip_request_t *message_request=NULL;
	belle_sip_request_t *clone_request=NULL;
	// belle_sip_header_authorization_t * h=NULL;

	is_register_ok = 0;

	message_request=belle_sip_request_create(
								belle_sip_uri_parse("sip:sip.linphone.org;transport=tcp")
								,"MESSAGE"
								,belle_sip_provider_create_call_id(prov)
								,belle_sip_header_cseq_create(22,"MESSAGE")
								,belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(initial_request), belle_sip_header_from_t)
								,belle_sip_header_to_parse("To: sip:marie@sip.linphone.org")
								,belle_sip_header_via_new()
								,70);
	belle_sip_message_add_header(BELLE_SIP_MESSAGE(message_request),BELLE_SIP_HEADER(belle_sip_header_expires_create(600)));
	belle_sip_message_add_header(BELLE_SIP_MESSAGE(message_request),BELLE_SIP_HEADER(belle_sip_header_contact_new()));
	belle_sip_provider_add_authorization(prov,message_request,NULL,NULL,NULL,realm);
	// h = belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(message_request), belle_sip_header_authorization_t);
	/*if a matching authorization was found, use it as a proxy authorization*/
	// if (h != NULL){
	// 	belle_sip_header_set_name(BELLE_SIP_HEADER(h), BELLE_SIP_PROXY_AUTHORIZATION);
	// }
	clone_request = (belle_sip_request_t*)belle_sip_object_ref(belle_sip_object_clone((belle_sip_object_t*)message_request));
jehan's avatar
jehan committed
796
	belle_sip_client_transaction_send_request_to(belle_sip_provider_create_client_transaction(prov,message_request),outbound);
797 798 799 800 801
	for(i=0; i<2 && io_error_count==0 &&is_register_ok==0;i++)
		belle_sip_stack_sleep(stack,5000);

	return clone_request;
}
jehan's avatar
jehan committed
802 803 804 805 806 807

static belle_sip_request_t* send_message(belle_sip_request_t *initial_request, const char* realm) {
	return send_message_to(initial_request,realm,NULL);
}

static void reuse_nonce_base(const char* outbound) {
808
	belle_sip_request_t *register_request;
jehan's avatar
jehan committed
809 810 811 812 813 814 815 816 817 818
	size_t initial_auth_context_count=0;/*belle_sip_list_size(prov->auth_contexts);*/
	char outbound_uri[256];
	/*reset auth context*/
	prov->auth_contexts = belle_sip_list_free_with_data(prov->auth_contexts,(void(*)(void*))belle_sip_authorization_destroy);
	
	if (outbound)
		snprintf(outbound_uri, sizeof(outbound_uri),"sip:%s",outbound);
	
	register_request=register_user_at_domain(stack, prov, "tcp",1,"marie",outbound,NULL);
	
819 820 821
	if (register_request) {
		belle_sip_header_authorization_t * h = NULL;
		belle_sip_request_t *message_request;
jehan's avatar
jehan committed
822 823 824 825 826 827 828 829 830 831 832 833 834
		belle_sip_listener_callbacks_t cbs;
		belle_sip_listener_t *reuse_nonce_listener;
		cbs.process_dialog_terminated=process_dialog_terminated;
		cbs.process_io_error=process_io_error;
		cbs.process_request_event=process_request_event;
		cbs.process_response_event=process_message_response_event;
		cbs.process_timeout=process_timeout;
		cbs.process_transaction_terminated=process_transaction_terminated;
		cbs.process_auth_requested=process_auth_requested;
		cbs.listener_destroyed=NULL;
		reuse_nonce_listener=belle_sip_listener_create_from_callbacks(&cbs,NULL);

		belle_sip_provider_add_sip_listener(prov,BELLE_SIP_LISTENER(reuse_nonce_listener));
835 836

		/*currently only one nonce should have been used (the one for the REGISTER)*/
837
		BC_ASSERT_EQUAL((unsigned int)belle_sip_list_size(prov->auth_contexts), (unsigned int)initial_auth_context_count+1,unsigned int,"%u");
838 839

		/*this should reuse previous nonce*/
jehan's avatar
jehan committed
840
		message_request=send_message_to(register_request, auth_domain,outbound?belle_sip_uri_parse(outbound_uri):NULL);
841
		BC_ASSERT_EQUAL(is_register_ok, 404,int,"%d");
842
		h = BELLE_SIP_HEADER_AUTHORIZATION(belle_sip_message_get_header_by_type(
843 844
					BELLE_SIP_MESSAGE(message_request), belle_sip_header_proxy_authorization_t
				));
jehan's avatar
jehan committed
845 846 847
		if (BC_ASSERT_PTR_NOT_NULL(h)
			&& belle_sip_header_authorization_get_qop(h)
			&& strcmp(belle_sip_header_authorization_get_qop(h),"auth")==0) {
848 849 850 851 852
			char * first_nonce_used;
			BC_ASSERT_EQUAL(2, belle_sip_header_authorization_get_nonce_count(h),int,"%d");
			first_nonce_used = belle_sip_strdup(belle_sip_header_authorization_get_nonce(h));
			belle_sip_free(first_nonce_used);
		}
853 854 855 856
		belle_sip_object_unref(message_request);


		/*new nonce should be created when not using outbound proxy realm*/
jehan's avatar
jehan committed
857
		message_request=send_message_to(register_request, NULL,outbound?belle_sip_uri_parse(outbound_uri):NULL);
858
		BC_ASSERT_EQUAL(is_register_ok, 407,int,"%d");
859 860 861
		h = BELLE_SIP_HEADER_AUTHORIZATION(belle_sip_message_get_header_by_type(
				BELLE_SIP_MESSAGE(message_request), belle_sip_header_proxy_authorization_t
			));
862
		BC_ASSERT_PTR_NULL(h);
863 864 865 866
		belle_sip_object_unref(message_request);


		/*new nonce should be created here too*/
jehan's avatar
jehan committed
867
		message_request=send_message_to(register_request, "wrongrealm",outbound?belle_sip_uri_parse(outbound_uri):NULL);
868
		BC_ASSERT_EQUAL(is_register_ok, 407,int,"%d");
869 870 871
		h = BELLE_SIP_HEADER_AUTHORIZATION(belle_sip_message_get_header_by_type(
				BELLE_SIP_MESSAGE(message_request), belle_sip_header_proxy_authorization_t
			));
872
		BC_ASSERT_PTR_NULL(h);
873 874 875
		belle_sip_object_unref(message_request);


jehan's avatar
jehan committed
876 877 878
		/*first nonce created should be reused. this test is only for qop = auth*/
		message_request=send_message_to(register_request, auth_domain,outbound?belle_sip_uri_parse(outbound_uri):NULL);
		
879 880 881
		h = BELLE_SIP_HEADER_AUTHORIZATION(belle_sip_message_get_header_by_type(
				BELLE_SIP_MESSAGE(message_request), belle_sip_header_proxy_authorization_t
			));
jehan's avatar
jehan committed
882 883 884 885
		if (BC_ASSERT_PTR_NOT_NULL(h)
			&& belle_sip_header_authorization_get_qop(h)
			&& strcmp(belle_sip_header_authorization_get_qop(h),"auth")==0) {
			BC_ASSERT_EQUAL(is_register_ok, 404,int,"%d");
886 887
			BC_ASSERT_EQUAL(3, belle_sip_header_authorization_get_nonce_count(h),int,"%d");
		}
888 889
		belle_sip_object_unref(message_request);

jehan's avatar
jehan committed
890
		belle_sip_provider_remove_sip_listener(prov,BELLE_SIP_LISTENER(reuse_nonce_listener));
891 892 893 894
		unregister_user(stack,prov,register_request,1);
		belle_sip_object_unref(register_request);
	}
}
jehan's avatar
jehan committed
895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949
static void reuse_nonce(void) {
	reuse_nonce_base("sip.linphone.org");
}
#define NONCE_SIZE  32
void register_process_request_event(char *nonce, const belle_sip_request_event_t *event) {
	belle_sip_request_t *req = belle_sip_request_event_get_request(event);
	belle_sip_header_authorization_t *authorization;
	int response_code = 407;
	char *uri_as_string= belle_sip_uri_to_string(belle_sip_request_get_uri(req));
	belle_sip_response_t * response_msg;
	belle_sip_server_transaction_t *trans=belle_sip_provider_create_server_transaction(prov, req);
	
	if (strcasecmp(belle_sip_request_get_method(req), "REGISTER") == 0) {
		response_code=401;
	}
	
	if (	(authorization = belle_sip_message_get_header_by_type(req,belle_sip_header_authorization_t))
		 || (authorization = BELLE_SIP_HEADER_AUTHORIZATION(belle_sip_message_get_header_by_type(req,belle_sip_header_proxy_authorization_t)))) {
		 char ha1[33], ha2[33], response[33];
		belle_sip_auth_helper_compute_ha1(belle_sip_header_authorization_get_username(authorization)
										, belle_sip_header_authorization_get_realm(authorization)
										  ,"secret", ha1);
		belle_sip_auth_helper_compute_ha2(belle_sip_request_get_method(req)
										  , uri_as_string, ha2);
		belle_sip_auth_helper_compute_response(ha1,nonce, ha2, response);
		if (strcmp(response, belle_sip_header_authorization_get_response(authorization)) == 0) {
			belle_sip_message("Auth sucessfull");
			if (strcasecmp(belle_sip_request_get_method(req), "MESSAGE") == 0) {
				response_code = 404;
			} else {
				response_code = 200;
			}
		}
	}
	
	belle_sip_random_token((nonce), NONCE_SIZE);
	response_msg = belle_sip_response_create_from_request(req, response_code);
	
	if (response_code == 407 || response_code == 401 ) {
		belle_sip_header_www_authenticate_t *www_authenticate = 401?belle_sip_header_www_authenticate_new():BELLE_SIP_HEADER_WWW_AUTHENTICATE(belle_sip_header_proxy_authenticate_new());
	
		
		belle_sip_header_www_authenticate_set_realm(www_authenticate, "sip.linphone.org");
		belle_sip_header_www_authenticate_set_domain(www_authenticate, "sip:sip.linphone.org");
		belle_sip_header_www_authenticate_set_scheme(www_authenticate, "Digest");
		belle_sip_header_www_authenticate_set_nonce(www_authenticate,nonce);
		belle_sip_message_add_header(BELLE_SIP_MESSAGE(response_msg), BELLE_SIP_HEADER(www_authenticate));
	} else {
		belle_sip_header_authentication_info_t* authentication_info = belle_sip_header_authentication_info_new();
		belle_sip_header_authentication_info_set_next_nonce(authentication_info, nonce);
		belle_sip_message_add_header(BELLE_SIP_MESSAGE(response_msg), BELLE_SIP_HEADER(authentication_info));
	}
	
	belle_sip_server_transaction_send_response(trans,response_msg);
}
950

jehan's avatar
jehan committed
951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975
static void test_register_with_next_nonce() {
	belle_sip_listening_point_t *server_lp = belle_sip_stack_create_listening_point(stack,"0.0.0.0",bctbx_random()%20000 +1024,"TCP");
	char  nonce [NONCE_SIZE];
	belle_sip_listener_t *server_listener;
	char listening_uri[256];
	belle_sip_listener_callbacks_t cbs;
	belle_sip_random_token((nonce), sizeof(nonce));
	
	cbs.process_dialog_terminated=NULL;
	cbs.process_io_error=NULL;
	cbs.process_request_event=(void (*)(void *user_ctx, const belle_sip_request_event_t *event))register_process_request_event;
	cbs.process_response_event=NULL;
	cbs.process_timeout=NULL;
	cbs.process_transaction_terminated=NULL;
	cbs.process_auth_requested=NULL;
	cbs.listener_destroyed=NULL;
	server_listener=belle_sip_listener_create_from_callbacks(&cbs,nonce);
	belle_sip_provider_add_sip_listener(prov,server_listener);
	belle_sip_provider_add_listening_point(prov,server_lp);
	snprintf(listening_uri,sizeof(listening_uri), "127.0.0.1:%i;transport=tcp",belle_sip_listening_point_get_port(server_lp));

	reuse_nonce_base(listening_uri);
	belle_sip_provider_remove_sip_listener(prov, server_listener);
	belle_sip_provider_remove_listening_point(prov, server_lp);
}
976

Ghislain MARY's avatar
Ghislain MARY committed
977
test_t register_tests[] = {
978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994
	TEST_NO_TAG("Stateful UDP", stateful_register_udp),
	TEST_NO_TAG("Stateful UDP with keep-alive", stateful_register_udp_with_keep_alive),
	TEST_NO_TAG("Stateful UDP with network delay", stateful_register_udp_delayed),
	TEST_NO_TAG("Stateful UDP with send error", stateful_register_udp_with_send_error),
	TEST_NO_TAG("Stateful UDP with outbound proxy", stateful_register_udp_with_outbound_proxy),
	TEST_NO_TAG("Stateful TCP", stateful_register_tcp),
	TEST_NO_TAG("Stateful TLS", stateful_register_tls),
	TEST_NO_TAG("Stateful TLS with wrong cname", stateful_register_tls_with_wrong_cname),
	TEST_NO_TAG("Stateful TLS with http proxy", stateful_register_tls_with_http_proxy),
	TEST_NO_TAG("Stateful TLS with wrong http proxy", stateful_register_tls_with_wrong_http_proxy),
	TEST_NO_TAG("Stateless UDP", stateless_register_udp),
	TEST_NO_TAG("Stateless TCP", stateless_register_tcp),
	TEST_NO_TAG("Stateless TLS", stateless_register_tls),
	TEST_NO_TAG("Bad TCP request", test_bad_request),
	TEST_NO_TAG("Authenticate", test_register_authenticate),
	TEST_NO_TAG("TLS client cert authentication", test_register_client_authenticated),
	TEST_NO_TAG("Channel inactive", test_register_channel_inactive),
995
	TEST_NO_TAG("Channel moving to error test and cleaned", test_channel_moving_to_error_and_cleaned),
996 997 998 999 1000 1001 1002 1003
	TEST_NO_TAG("TCP connection failure", test_connection_failure),
	TEST_NO_TAG("TCP connection too long", test_connection_too_long_tcp),
	TEST_NO_TAG("TLS connection too long", test_connection_too_long_tls),
	TEST_NO_TAG("TLS connection to TCP server", test_tls_to_tcp),
	TEST_NO_TAG("Register with DNS SRV failover TCP", register_dns_srv_tcp),
	TEST_NO_TAG("Register with DNS SRV failover TLS", register_dns_srv_tls),
	TEST_NO_TAG("Register with DNS SRV failover TLS with http proxy", register_dns_srv_tls_with_http_proxy),
	TEST_NO_TAG("Register with DNS load-balancing", register_dns_load_balancing),
jehan's avatar
jehan committed
1004 1005
	TEST_NO_TAG("Nonce reutilization", reuse_nonce),
	TEST_NO_TAG("Next Nonce", test_register_with_next_nonce)
Ghislain MARY's avatar
Ghislain MARY committed
1006 1007
};

1008
test_suite_t register_test_suite = {"Register", register_before_all, register_after_all, NULL,
Simon Morlat's avatar
Simon Morlat committed
1009
									NULL, sizeof(register_tests) / sizeof(register_tests[0]),
1010
									register_tests};