2 * @file sip-transport.c
6 * Copyright (C) 2010-2013 SIPE Project <http://sipe.sourceforge.net/>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 * This module incapsulates SIP (RFC3261) protocol and provides
25 * higher level API (a layer) to XML-based SIPE (SIP with Extensions).
26 * Underlying leyer for this is TCP/SSL layer.
28 * A diagram in pseudographics:
30 * === SIPE (XML-based) layer ======================
31 * === SIP RFC3261 transport layer (This module) ===
32 * === TCP/SSL layer ===============================
34 * Authentication (Kerberos and NTLM) is applicable to this layer only.
35 * The same with message integtity (signing). No sip-sec* code should
36 * be used ourside of this module.
38 * SIP errors as codes(both as a return codes and network conditions) should be
39 * escalated to higher leyer (SIPE). Network conditions include no response
40 * within timeout interval.
42 * This module should support redirect internally. No escalations to higher
45 * NO SIP-messages (headers) composing and processing should be outside of
46 * this module (!) Like headers: Via, Route, Contact, Authorization, etc.
47 * It's all irrelevant to higher layer responsibilities.
61 #include "sipe-common.h"
64 #include "sip-sec-digest.h"
65 #include "sip-transport.h"
66 #include "sipe-backend.h"
67 #include "sipe-core.h"
68 #include "sipe-core-private.h"
69 #include "sipe-certificate.h"
70 #include "sipe-dialog.h"
71 #include "sipe-incoming.h"
73 #include "sipe-notify.h"
74 #include "sipe-schedule.h"
75 #include "sipe-sign.h"
76 #include "sipe-subscriptions.h"
77 #include "sipe-utils.h"
81 struct sip_sec_context
*gssapi_context
;
84 const gchar
*protocol
;
94 /* sip-transport.c private data */
95 struct sip_transport
{
96 struct sipe_transport_connection
*connection
;
100 gchar
*server_version
;
104 GSList
*transactions
;
106 struct sip_auth registrar
;
107 struct sip_auth proxy
;
110 guint register_attempt
;
112 gboolean processing_input
; /* whether full header received */
113 gboolean auth_incomplete
; /* whether authentication not completed */
114 gboolean reregister_set
; /* whether reregister timer set */
115 gboolean reauthenticate_set
; /* whether reauthenticate timer set */
116 gboolean subscribed
; /* whether subscribed to events, except buddies presence */
117 gboolean deregister
; /* whether in deregistration */
120 /* Keep in sync with sipe_transport_type! */
121 static const char *transport_descriptor
[] = { "", "tls", "tcp"};
122 #define TRANSPORT_DESCRIPTOR (transport_descriptor[transport->connection->type])
124 static char *genbranch()
126 return g_strdup_printf("z9hG4bK%04X%04X%04X%04X%04X",
127 rand() & 0xFFFF, rand() & 0xFFFF, rand() & 0xFFFF,
128 rand() & 0xFFFF, rand() & 0xFFFF);
131 static void sipe_auth_free(struct sip_auth
*auth
)
133 g_free(auth
->opaque
);
135 auth
->protocol
= NULL
;
138 g_free(auth
->sts_uri
);
139 auth
->sts_uri
= NULL
;
140 g_free(auth
->target
);
143 auth
->type
= SIPE_AUTHENTICATION_TYPE_UNSET
;
146 g_free(auth
->gssapi_data
);
147 auth
->gssapi_data
= NULL
;
148 sip_sec_destroy_context(auth
->gssapi_context
);
149 auth
->gssapi_context
= NULL
;
152 static void sipe_make_signature(struct sipe_core_private
*sipe_private
,
155 struct sip_transport
*transport
= sipe_private
->transport
;
156 if (sip_sec_context_is_ready(transport
->registrar
.gssapi_context
)) {
157 struct sipmsg_breakdown msgbd
;
158 gchar
*signature_input_str
;
160 sipmsg_breakdown_parse(&msgbd
, transport
->registrar
.realm
, transport
->registrar
.target
,
161 transport
->registrar
.protocol
);
162 msgbd
.rand
= g_strdup_printf("%08x", g_random_int());
163 transport
->registrar
.ntlm_num
++;
164 msgbd
.num
= g_strdup_printf("%d", transport
->registrar
.ntlm_num
);
165 signature_input_str
= sipmsg_breakdown_get_string(transport
->registrar
.version
, &msgbd
);
166 if (signature_input_str
!= NULL
) {
167 char *signature_hex
= sip_sec_make_signature(transport
->registrar
.gssapi_context
, signature_input_str
);
168 msg
->signature
= signature_hex
;
169 msg
->rand
= g_strdup(msgbd
.rand
);
170 msg
->num
= g_strdup(msgbd
.num
);
171 g_free(signature_input_str
);
173 sipmsg_breakdown_free(&msgbd
);
177 static const gchar
*const auth_type_to_protocol
[] = {
178 NULL
, /* SIPE_AUTHENTICATION_TYPE_UNSET */
179 NULL
, /* SIPE_AUTHENTICATION_TYPE_BASIC */
180 "NTLM", /* SIPE_AUTHENTICATION_TYPE_NTLM */
181 "Kerberos", /* SIPE_AUTHENTICATION_TYPE_KERBEROS */
182 NULL
, /* SIPE_AUTHENTICATION_TYPE_NEGOTIATE */
183 "TLS-DSK", /* SIPE_AUTHENTICATION_TYPE_TLS_DSK */
185 #define AUTH_PROTOCOLS (sizeof(auth_type_to_protocol)/sizeof(gchar *))
187 static gchar
*msg_signature_to_auth(struct sip_auth
*auth
,
190 return(g_strdup_printf("%s qop=\"auth\", opaque=\"%s\", realm=\"%s\", targetname=\"%s\", crand=\"%s\", cnum=\"%s\", response=\"%s\"",
192 auth
->opaque
, auth
->realm
, auth
->target
,
193 msg
->rand
, msg
->num
, msg
->signature
));
196 static gchar
*initialize_auth_context(struct sipe_core_private
*sipe_private
,
197 struct sip_auth
*auth
,
200 struct sip_transport
*transport
= sipe_private
->transport
;
202 gchar
*gssapi_data
= NULL
;
209 * If transport is de-registering when we reach this point then we
210 * are in the middle of the previous authentication context setup
211 * attempt. So we shouldn't try another attempt.
213 if (transport
->deregister
)
216 /* Create security context or handshake continuation? */
217 if (auth
->gssapi_context
) {
218 /* Perform next step in authentication handshake */
219 gboolean status
= sip_sec_init_context_step(auth
->gssapi_context
,
225 /* If authentication is completed gssapi_data can be NULL */
227 (sip_sec_context_is_ready(auth
->gssapi_context
) || gssapi_data
))) {
228 SIPE_DEBUG_ERROR_NOFORMAT("initialize_auth_context: security context continuation failed");
230 sipe_backend_connection_error(SIPE_CORE_PUBLIC
,
231 SIPE_CONNECTION_ERROR_AUTHENTICATION_FAILED
,
232 _("Failed to authenticate to server"));
237 /* Create security context */
238 gpointer password
= sipe_private
->password
;
240 /* For TLS-DSK the "password" is a certificate */
241 if (auth
->type
== SIPE_AUTHENTICATION_TYPE_TLS_DSK
) {
242 password
= sipe_certificate_tls_dsk_find(sipe_private
,
247 SIPE_DEBUG_INFO("initialize_auth_context: TLS-DSK Certificate Provisioning URI %s",
249 if (!sipe_certificate_tls_dsk_generate(sipe_private
,
252 gchar
*tmp
= g_strdup_printf(_("Can't request certificate from %s"),
254 sipe_backend_connection_error(SIPE_CORE_PUBLIC
,
255 SIPE_CONNECTION_ERROR_AUTHENTICATION_FAILED
,
260 sipe_backend_connection_error(SIPE_CORE_PUBLIC
,
261 SIPE_CONNECTION_ERROR_AUTHENTICATION_FAILED
,
262 _("No URI for certificate provisioning service provided"));
265 /* we can't authenticate the message yet */
266 transport
->auth_incomplete
= TRUE
;
270 SIPE_DEBUG_INFO("initialize_auth_context: TLS-DSK certificate for target '%s' found.",
275 auth
->gssapi_context
= sip_sec_create_context(auth
->type
,
276 SIPE_CORE_PRIVATE_FLAG_IS(SSO
),
277 FALSE
, /* connection-less for SIP */
278 sipe_private
->authdomain
? sipe_private
->authdomain
: "",
279 sipe_private
->authuser
,
282 if (auth
->gssapi_context
) {
283 sip_sec_init_context_step(auth
->gssapi_context
,
290 if (!gssapi_data
|| !auth
->gssapi_context
) {
292 sipe_backend_connection_error(SIPE_CORE_PUBLIC
,
293 SIPE_CONNECTION_ERROR_AUTHENTICATION_FAILED
,
294 _("Failed to authenticate to server"));
299 if ((auth
->version
> 3) &&
300 sip_sec_context_is_ready(auth
->gssapi_context
)) {
301 sipe_make_signature(sipe_private
, msg
);
302 sign_str
= g_strdup_printf(", crand=\"%s\", cnum=\"%s\", response=\"%s\"",
303 msg
->rand
, msg
->num
, msg
->signature
);
305 sign_str
= g_strdup("");
309 gssapi_str
= g_strdup_printf(", gssapi-data=\"%s\"",
313 gssapi_str
= g_strdup("");
316 opaque_str
= auth
->opaque
? g_strdup_printf(", opaque=\"%s\"", auth
->opaque
) : g_strdup("");
318 if (auth
->version
> 2) {
319 version_str
= g_strdup_printf(", version=%d", auth
->version
);
321 version_str
= g_strdup("");
324 ret
= g_strdup_printf("%s qop=\"auth\"%s, realm=\"%s\", targetname=\"%s\"%s%s%s",
325 auth
->protocol
, opaque_str
,
326 auth
->realm
, auth
->target
,
327 gssapi_str
, version_str
, sign_str
);
336 static gchar
*auth_header(struct sipe_core_private
*sipe_private
,
337 struct sip_auth
*auth
,
343 * If the message is already signed then we have an authentication
344 * context, i.e. the authentication handshake is complete. Generate
345 * authentication header from message signature.
347 if (msg
->signature
) {
348 ret
= msg_signature_to_auth(auth
, msg
);
351 * We should reach this point only when the authentication context
352 * needs to be initialized.
355 ret
= initialize_auth_context(sipe_private
, auth
, msg
);
361 static void fill_auth(const gchar
*hdr
, struct sip_auth
*auth
)
365 /* skip authentication identifier */
366 hdr
= strchr(hdr
, ' ');
368 SIPE_DEBUG_ERROR_NOFORMAT("fill_auth: corrupted authentication header");
374 /* start of next parameter value */
375 while ((param
= strchr(hdr
, '=')) != NULL
) {
378 /* parameter value type */
381 /* string: xyz="..."(,) */
382 end
= strchr(++param
, '"');
384 SIPE_DEBUG_ERROR("fill_auth: corrupted string parameter near '%s'", hdr
);
388 /* number: xyz=12345(,) */
389 end
= strchr(param
, ',');
392 end
= param
+ strlen(param
);
397 SIPE_DEBUG_INFO("fill_auth: hdr '%s'", hdr
);
398 SIPE_DEBUG_INFO("fill_auth: param '%s'", param
);
399 SIPE_DEBUG_INFO("fill_auth: end '%s'", end
);
403 if (g_str_has_prefix(hdr
, "gssapi-data=\"")) {
404 g_free(auth
->gssapi_data
);
405 auth
->gssapi_data
= g_strndup(param
, end
- param
);
406 } else if (g_str_has_prefix(hdr
, "opaque=\"")) {
407 g_free(auth
->opaque
);
408 auth
->opaque
= g_strndup(param
, end
- param
);
409 } else if (g_str_has_prefix(hdr
, "realm=\"")) {
411 auth
->realm
= g_strndup(param
, end
- param
);
412 } else if (g_str_has_prefix(hdr
, "sts-uri=\"")) {
413 /* Only used with SIPE_AUTHENTICATION_TYPE_TLS_DSK */
414 g_free(auth
->sts_uri
);
415 auth
->sts_uri
= g_strndup(param
, end
- param
);
416 } else if (g_str_has_prefix(hdr
, "targetname=\"")) {
417 g_free(auth
->target
);
418 auth
->target
= g_strndup(param
, end
- param
);
419 } else if (g_str_has_prefix(hdr
, "version=")) {
420 auth
->version
= atoi(param
);
423 /* skip to next parameter */
424 while ((*end
== '"') || (*end
== ',') || (*end
== ' '))
432 static void sign_outgoing_message(struct sipe_core_private
*sipe_private
,
435 struct sip_transport
*transport
= sipe_private
->transport
;
438 if (transport
->registrar
.type
== SIPE_AUTHENTICATION_TYPE_UNSET
) {
442 sipe_make_signature(sipe_private
, msg
);
444 buf
= auth_header(sipe_private
, &transport
->registrar
, msg
);
446 sipmsg_add_header_now(msg
, "Authorization", buf
);
451 static const gchar
*sip_transport_user_agent(struct sipe_core_private
*sipe_private
)
453 struct sip_transport
*transport
= sipe_private
->transport
;
455 if (!transport
->user_agent
) {
456 const gchar
*useragent
= sipe_backend_setting(SIPE_CORE_PUBLIC
,
457 SIPE_SETTING_USER_AGENT
);
458 if (is_empty(useragent
)) {
459 /*@TODO: better approach to define _user_ OS, it's version and host architecture */
461 #if defined(__linux__) || defined(__linux) || defined(__LINUX__)
462 #define SIPE_TARGET_PLATFORM "linux"
463 #elif defined(__NetBSD__) ||defined( __OpenBSD__) || defined(__FreeBSD__)
464 #define SIPE_TARGET_PLATFORM "bsd"
465 #elif defined(__APPLE__) || defined(__MACOS__)
466 #define SIPE_TARGET_PLATFORM "macosx"
467 #elif defined(_AIX) || defined(__AIX__) || defined(__aix__)
468 #define SIPE_TARGET_PLATFORM "aix"
469 #elif defined(__solaris__) || defined(__sun)
470 #define SIPE_TARGET_PLATFORM "sun"
471 #elif defined(_WIN32)
472 #define SIPE_TARGET_PLATFORM "win"
473 #elif defined(__CYGWIN__)
474 #define SIPE_TARGET_PLATFORM "cygwin"
475 #elif defined(__hpux__)
476 #define SIPE_TARGET_PLATFORM "hpux"
477 #elif defined(__sgi__)
478 #define SIPE_TARGET_PLATFORM "irix"
480 #define SIPE_TARGET_PLATFORM "unknown"
483 #if defined(__amd64__) || defined(__x86_64__) || defined(_M_AMD64)
484 #define SIPE_TARGET_ARCH "x86_64"
485 #elif defined(__386__) || defined(__i386__) || defined(__i386) || defined(_M_IX86) || defined(_M_I386)
486 #define SIPE_TARGET_ARCH "i386"
487 #elif defined(__ppc64__)
488 #define SIPE_TARGET_ARCH "ppc64"
489 #elif defined(__powerpc__) || defined(__powerpc) || defined(__ppc__) || defined(__PPC__) || defined(_M_PPC) || defined(_ARCH_PPC) || defined(_ARCH_PWR)
490 #define SIPE_TARGET_ARCH "ppc"
491 #elif defined(__hppa__) || defined(__hppa)
492 #define SIPE_TARGET_ARCH "hppa"
493 #elif defined(__mips__) || defined(__mips) || defined(_MIPS_ARCH) || defined(_M_MRX000)
494 #define SIPE_TARGET_ARCH "mips"
495 #elif defined(__s390__) || defined(__s390) || defined(__s390x__) || defined(__s390x)
496 #define SIPE_TARGET_ARCH "s390"
497 #elif defined(__sparc__) || defined(__sparc) || defined(__sparcv8)
498 #define SIPE_TARGET_ARCH "sparc"
499 #elif defined(__arm__)
500 #define SIPE_TARGET_ARCH "arm"
502 #define SIPE_TARGET_ARCH "other"
504 gchar
*backend
= sipe_backend_version();
505 transport
->user_agent
= g_strdup_printf("%s Sipe/" PACKAGE_VERSION
" (" SIPE_TARGET_PLATFORM
"-" SIPE_TARGET_ARCH
"; %s)",
507 transport
->server_version
? transport
->server_version
: "");
510 transport
->user_agent
= g_strdup(useragent
);
513 return(transport
->user_agent
);
516 void sip_transport_response(struct sipe_core_private
*sipe_private
,
524 GString
*outstr
= g_string_new("");
527 const gchar
*keepers
[] = { "To", "From", "Call-ID", "CSeq", "Via", "Record-Route", NULL
};
529 /* Can return NULL! */
530 contact
= get_contact(sipe_private
);
532 sipmsg_add_header(msg
, "Contact", contact
);
537 gchar
*len
= g_strdup_printf("%" G_GSIZE_FORMAT
, (gsize
) strlen(body
));
538 sipmsg_add_header(msg
, "Content-Length", len
);
541 sipmsg_add_header(msg
, "Content-Length", "0");
544 sipmsg_add_header(msg
, "User-Agent", sip_transport_user_agent(sipe_private
));
546 msg
->response
= code
;
548 sipmsg_strip_headers(msg
, keepers
);
549 sipmsg_merge_new_headers(msg
);
550 sign_outgoing_message(sipe_private
, msg
);
552 g_string_append_printf(outstr
, "SIP/2.0 %d %s\r\n", code
, text
);
555 name
= ((struct sipnameval
*) (tmp
->data
))->name
;
556 value
= ((struct sipnameval
*) (tmp
->data
))->value
;
558 g_string_append_printf(outstr
, "%s: %s\r\n", name
, value
);
559 tmp
= g_slist_next(tmp
);
561 g_string_append_printf(outstr
, "\r\n%s", body
? body
: "");
562 sipe_utils_message_debug("SIP", outstr
->str
, NULL
, TRUE
);
563 sipe_backend_transport_message(sipe_private
->transport
->connection
, outstr
->str
);
564 g_string_free(outstr
, TRUE
);
567 static void transactions_remove(struct sipe_core_private
*sipe_private
,
568 struct transaction
*trans
)
570 struct sip_transport
*transport
= sipe_private
->transport
;
571 if (transport
->transactions
) {
572 transport
->transactions
= g_slist_remove(transport
->transactions
,
574 SIPE_DEBUG_INFO("SIP transactions count:%d after removal", g_slist_length(transport
->transactions
));
576 if (trans
->msg
) sipmsg_free(trans
->msg
);
577 if (trans
->payload
) {
578 if (trans
->payload
->destroy
)
579 (*trans
->payload
->destroy
)(trans
->payload
->data
);
580 g_free(trans
->payload
);
583 if (trans
->timeout_key
) {
584 sipe_schedule_cancel(sipe_private
, trans
->timeout_key
);
585 g_free(trans
->timeout_key
);
591 static struct transaction
*transactions_find(struct sip_transport
*transport
,
594 GSList
*transactions
= transport
->transactions
;
595 const gchar
*call_id
= sipmsg_find_header(msg
, "Call-ID");
596 const gchar
*cseq
= sipmsg_find_header(msg
, "CSeq");
599 if (!call_id
|| !cseq
) {
600 SIPE_DEBUG_ERROR_NOFORMAT("transaction_find: no Call-ID or CSeq!");
604 key
= g_strdup_printf("<%s><%s>", call_id
, cseq
);
605 while (transactions
) {
606 struct transaction
*trans
= transactions
->data
;
607 if (!g_ascii_strcasecmp(trans
->key
, key
)) {
611 transactions
= transactions
->next
;
618 static void transaction_timeout_cb(struct sipe_core_private
*sipe_private
,
621 struct transaction
*trans
= data
;
622 (trans
->timeout_callback
)(sipe_private
, trans
->msg
, trans
);
623 transactions_remove(sipe_private
, trans
);
626 struct transaction
*sip_transport_request_timeout(struct sipe_core_private
*sipe_private
,
630 const gchar
*addheaders
,
632 struct sip_dialog
*dialog
,
633 TransCallback callback
,
635 TransCallback timeout_callback
)
637 struct sip_transport
*transport
= sipe_private
->transport
;
640 gchar
*ourtag
= dialog
&& dialog
->ourtag
? g_strdup(dialog
->ourtag
) : NULL
;
641 gchar
*theirtag
= dialog
&& dialog
->theirtag
? g_strdup(dialog
->theirtag
) : NULL
;
642 gchar
*theirepid
= dialog
&& dialog
->theirepid
? g_strdup(dialog
->theirepid
) : NULL
;
643 gchar
*callid
= dialog
&& dialog
->callid
? g_strdup(dialog
->callid
) : gencallid();
644 gchar
*branch
= dialog
&& dialog
->callid
? NULL
: genbranch();
645 gchar
*route
= g_strdup("");
646 gchar
*epid
= get_epid(sipe_private
);
647 int cseq
= dialog
? ++dialog
->cseq
: 1 /* as Call-Id is new in this case */;
648 struct transaction
*trans
= NULL
;
650 if (dialog
&& dialog
->routes
)
652 GSList
*iter
= dialog
->routes
;
657 route
= g_strdup_printf("%sRoute: %s\r\n", route
, (char *)iter
->data
);
659 iter
= g_slist_next(iter
);
663 if (!ourtag
&& !dialog
) {
667 if (sipe_strequal(method
, "REGISTER")) {
668 if (sipe_private
->register_callid
) {
670 callid
= g_strdup(sipe_private
->register_callid
);
672 sipe_private
->register_callid
= g_strdup(callid
);
674 cseq
= ++transport
->cseq
;
677 buf
= g_strdup_printf("%s %s SIP/2.0\r\n"
678 "Via: SIP/2.0/%s %s:%d%s%s\r\n"
679 "From: <sip:%s>%s%s;epid=%s\r\n"
680 "To: <%s>%s%s%s%s\r\n"
681 "Max-Forwards: 70\r\n"
686 "Content-Length: %" G_GSIZE_FORMAT
"\r\n\r\n%s",
688 dialog
&& dialog
->request
? dialog
->request
: url
,
689 TRANSPORT_DESCRIPTOR
,
690 sipe_backend_network_ip_address(SIPE_CORE_PUBLIC
),
691 transport
->connection
->client_port
,
692 branch
? ";branch=" : "",
693 branch
? branch
: "",
694 sipe_private
->username
,
695 ourtag
? ";tag=" : "",
696 ourtag
? ourtag
: "",
699 theirtag
? ";tag=" : "",
700 theirtag
? theirtag
: "",
701 theirepid
? ";epid=" : "",
702 theirepid
? theirepid
: "",
705 sip_transport_user_agent(sipe_private
),
708 addheaders
? addheaders
: "",
709 body
? (gsize
) strlen(body
) : 0,
713 //printf ("parsing msg buf:\n%s\n\n", buf);
714 msg
= sipmsg_parse_msg(buf
);
724 sign_outgoing_message(sipe_private
, msg
);
726 /* The authentication scheme is not ready so we can't send the message.
727 This should only happen for REGISTER messages. */
728 if (!transport
->auth_incomplete
) {
729 buf
= sipmsg_to_string(msg
);
731 /* add to ongoing transactions */
732 /* ACK isn't supposed to be answered ever. So we do not keep transaction for it. */
733 if (!sipe_strequal(method
, "ACK")) {
734 trans
= g_new0(struct transaction
, 1);
735 trans
->callback
= callback
;
737 trans
->key
= g_strdup_printf("<%s><%d %s>", callid
, cseq
, method
);
738 if (timeout_callback
) {
739 trans
->timeout_callback
= timeout_callback
;
740 trans
->timeout_key
= g_strdup_printf("<transaction timeout>%s", trans
->key
);
741 sipe_schedule_seconds(sipe_private
,
745 transaction_timeout_cb
,
748 transport
->transactions
= g_slist_append(transport
->transactions
,
750 SIPE_DEBUG_INFO("SIP transactions count:%d after addition", g_slist_length(transport
->transactions
));
753 sipe_utils_message_debug("SIP", buf
, NULL
, TRUE
);
754 sipe_backend_transport_message(transport
->connection
, buf
);
758 if (!trans
) sipmsg_free(msg
);
763 struct transaction
*sip_transport_request(struct sipe_core_private
*sipe_private
,
767 const gchar
*addheaders
,
769 struct sip_dialog
*dialog
,
770 TransCallback callback
)
772 return sip_transport_request_timeout(sipe_private
,
784 static void sip_transport_simple_request(struct sipe_core_private
*sipe_private
,
786 struct sip_dialog
*dialog
)
788 sip_transport_request(sipe_private
,
798 void sip_transport_ack(struct sipe_core_private
*sipe_private
,
799 struct sip_dialog
*dialog
)
801 sip_transport_simple_request(sipe_private
, "ACK", dialog
);
804 void sip_transport_bye(struct sipe_core_private
*sipe_private
,
805 struct sip_dialog
*dialog
)
807 sip_transport_simple_request(sipe_private
, "BYE", dialog
);
810 struct transaction
*sip_transport_info(struct sipe_core_private
*sipe_private
,
811 const gchar
*addheaders
,
813 struct sip_dialog
*dialog
,
814 TransCallback callback
)
816 return sip_transport_request(sipe_private
,
826 struct transaction
*sip_transport_invite(struct sipe_core_private
*sipe_private
,
827 const gchar
*addheaders
,
829 struct sip_dialog
*dialog
,
830 TransCallback callback
)
832 return sip_transport_request(sipe_private
,
842 struct transaction
*sip_transport_service(struct sipe_core_private
*sipe_private
,
844 const gchar
*addheaders
,
846 TransCallback callback
)
848 return sip_transport_request(sipe_private
,
858 void sip_transport_subscribe(struct sipe_core_private
*sipe_private
,
860 const gchar
*addheaders
,
862 struct sip_dialog
*dialog
,
863 TransCallback callback
)
865 sip_transport_request(sipe_private
,
875 void sip_transport_update(struct sipe_core_private
*sipe_private
,
876 struct sip_dialog
*dialog
)
878 sip_transport_simple_request(sipe_private
, "UPDATE", dialog
);
881 static const gchar
*get_auth_header(struct sipe_core_private
*sipe_private
,
882 struct sip_auth
*auth
,
885 auth
->type
= sipe_private
->authentication_type
;
886 auth
->protocol
= auth_type_to_protocol
[auth
->type
];
888 return(sipmsg_find_auth_header(msg
, auth
->protocol
));
891 static void do_register(struct sipe_core_private
*sipe_private
,
892 gboolean deregister
);
894 static void do_reauthenticate_cb(struct sipe_core_private
*sipe_private
,
895 SIPE_UNUSED_PARAMETER gpointer unused
)
897 struct sip_transport
*transport
= sipe_private
->transport
;
899 /* register again when security token expires */
900 /* we have to start a new authentication as the security token
901 * is almost expired by sending a not signed REGISTER message */
902 SIPE_DEBUG_INFO_NOFORMAT("do a full reauthentication");
903 sipe_auth_free(&transport
->registrar
);
904 sipe_auth_free(&transport
->proxy
);
905 sipe_schedule_cancel(sipe_private
, "<registration>");
906 transport
->reregister_set
= FALSE
;
907 transport
->register_attempt
= 0;
908 do_register(sipe_private
, FALSE
);
909 transport
->reauthenticate_set
= FALSE
;
912 static void sip_transport_default_contact(struct sipe_core_private
*sipe_private
)
914 struct sip_transport
*transport
= sipe_private
->transport
;
915 sipe_private
->contact
= g_strdup_printf("<sip:%s:%d;maddr=%s;transport=%s>;proxy=replace",
916 sipe_private
->username
,
917 transport
->connection
->client_port
,
918 sipe_backend_network_ip_address(SIPE_CORE_PUBLIC
),
919 TRANSPORT_DESCRIPTOR
);
922 static void do_register_cb(struct sipe_core_private
*sipe_private
,
923 SIPE_UNUSED_PARAMETER
void *unused
)
925 do_register(sipe_private
, FALSE
);
928 static void sip_transport_set_reregister(struct sipe_core_private
*sipe_private
,
931 sipe_schedule_seconds(sipe_private
,
939 static void sipe_server_register(struct sipe_core_private
*sipe_private
,
944 static gboolean
process_register_response(struct sipe_core_private
*sipe_private
,
946 SIPE_UNUSED_PARAMETER
struct transaction
*trans
)
948 struct sip_transport
*transport
= sipe_private
->transport
;
949 const gchar
*expires_header
;
951 GSList
*hdr
= msg
->headers
;
952 struct sipnameval
*elem
;
954 expires_header
= sipmsg_find_header(msg
, "Expires");
955 expires
= expires_header
!= NULL
? strtol(expires_header
, NULL
, 10) : 0;
956 SIPE_DEBUG_INFO("process_register_response: got response to REGISTER; expires = %d", expires
);
958 switch (msg
->response
) {
961 const gchar
*contact_hdr
;
962 const gchar
*auth_hdr
;
966 const gchar
*server_hdr
= sipmsg_find_header(msg
, "Server");
968 if (!transport
->reregister_set
) {
969 sip_transport_set_reregister(sipe_private
,
971 transport
->reregister_set
= TRUE
;
974 if (server_hdr
&& !transport
->server_version
) {
975 transport
->server_version
= g_strdup(server_hdr
);
976 g_free(transport
->user_agent
);
977 transport
->user_agent
= NULL
;
980 auth_hdr
= get_auth_header(sipe_private
, &transport
->registrar
, msg
);
982 SIPE_DEBUG_INFO("process_register_response: Auth header: %s", auth_hdr
);
983 fill_auth(auth_hdr
, &transport
->registrar
);
986 if (!transport
->reauthenticate_set
) {
987 gchar
*action_name
= g_strdup_printf("<%s>", "+reauthentication");
988 guint reauth_timeout
= transport
->registrar
.expires
;
990 SIPE_DEBUG_INFO_NOFORMAT("process_register_response: authentication handshake completed successfully");
992 /* Does authentication scheme provide valid expiration time? */
993 if (reauth_timeout
<= (5 * 60)) {
994 SIPE_DEBUG_INFO_NOFORMAT("process_register_response: no expiration time - using default of 8 hours");
995 reauth_timeout
= 8 * 60 * 60;
998 /* schedule reauthentication 5 minutes before expiration */
999 sipe_schedule_seconds(sipe_private
,
1002 reauth_timeout
- 5 * 60,
1003 do_reauthenticate_cb
,
1005 g_free(action_name
);
1006 transport
->reauthenticate_set
= TRUE
;
1009 sipe_backend_connection_completed(SIPE_CORE_PUBLIC
);
1011 uuid
= get_uuid(sipe_private
);
1013 // There can be multiple Contact headers (one per location where the user is logged in) so
1014 // make sure to only get the one for this uuid
1015 for (i
= 0; (contact_hdr
= sipmsg_find_header_instance (msg
, "Contact", i
)); i
++) {
1016 gchar
* valid_contact
= sipmsg_find_part_of_header (contact_hdr
, uuid
, NULL
, NULL
);
1017 if (valid_contact
) {
1018 gruu
= sipmsg_find_part_of_header(contact_hdr
, "gruu=\"", "\"", NULL
);
1019 //SIPE_DEBUG_INFO("process_register_response: got gruu %s from contact hdr w/ right uuid: %s", gruu, contact_hdr);
1020 g_free(valid_contact
);
1023 //SIPE_DEBUG_INFO("process_register_response: ignoring contact hdr b/c not right uuid: %s", contact_hdr);
1028 g_free(sipe_private
->contact
);
1030 sipe_private
->contact
= g_strdup_printf("<%s>", gruu
);
1033 //SIPE_DEBUG_INFO_NOFORMAT("process_register_response: didn't find gruu in a Contact hdr");
1034 sip_transport_default_contact(sipe_private
);
1036 SIPE_CORE_PRIVATE_FLAG_UNSET(OCS2007
);
1037 SIPE_CORE_PRIVATE_FLAG_UNSET(REMOTE_USER
);
1038 SIPE_CORE_PRIVATE_FLAG_UNSET(BATCHED_SUPPORT
);
1043 if (sipe_strcase_equal(elem
->name
, "Supported")) {
1044 if (sipe_strcase_equal(elem
->value
, "msrtc-event-categories")) {
1045 /* We interpret this as OCS2007+ indicator */
1046 SIPE_CORE_PRIVATE_FLAG_SET(OCS2007
);
1047 SIPE_DEBUG_INFO("Supported: %s (indicates OCS2007+)", elem
->value
);
1049 if (sipe_strcase_equal(elem
->value
, "adhoclist")) {
1050 SIPE_CORE_PRIVATE_FLAG_SET(BATCHED_SUPPORT
);
1051 SIPE_DEBUG_INFO("Supported: %s", elem
->value
);
1054 if (sipe_strcase_equal(elem
->name
, "Allow-Events")){
1055 gchar
**caps
= g_strsplit(elem
->value
,",",0);
1058 sipe_private
->allowed_events
= g_slist_append(sipe_private
->allowed_events
, g_strdup(caps
[i
]));
1059 SIPE_DEBUG_INFO("Allow-Events: %s", caps
[i
]);
1064 if (sipe_strcase_equal(elem
->name
, "ms-user-logon-data")) {
1065 if (sipe_strcase_equal(elem
->value
, "RemoteUser")) {
1066 SIPE_CORE_PRIVATE_FLAG_SET(REMOTE_USER
);
1067 SIPE_DEBUG_INFO_NOFORMAT("ms-user-logon-data: RemoteUser (connected "
1068 "via Edge Server)");
1071 hdr
= g_slist_next(hdr
);
1074 /* rejoin open chats to be able to use them by continue to send messages */
1075 sipe_backend_chat_rejoin_all(SIPE_CORE_PUBLIC
);
1077 /* subscriptions, done only once */
1078 if (!transport
->subscribed
) {
1079 sipe_subscription_self_events(sipe_private
);
1080 transport
->subscribed
= TRUE
;
1083 timeout
= sipmsg_find_part_of_header(sipmsg_find_header(msg
, "ms-keep-alive"),
1084 "timeout=", ";", NULL
);
1085 if (timeout
!= NULL
) {
1086 sscanf(timeout
, "%u", &sipe_private
->public.keepalive_timeout
);
1087 SIPE_DEBUG_INFO("process_register_response: server determined keep alive timeout is %u seconds",
1088 sipe_private
->public.keepalive_timeout
);
1092 SIPE_DEBUG_INFO("process_register_response: got 200, removing CSeq: %d", transport
->cseq
);
1097 gchar
*redirect
= parse_from(sipmsg_find_header(msg
, "Contact"));
1099 SIPE_DEBUG_INFO_NOFORMAT("process_register_response: authentication handshake completed successfully (with redirect)");
1101 if (redirect
&& (g_ascii_strncasecmp("sip:", redirect
, 4) == 0)) {
1102 gchar
**parts
= g_strsplit(redirect
+ 4, ";", 0);
1106 guint transport_type
= SIPE_TRANSPORT_TLS
;
1109 tmp
= g_strsplit(parts
[0], ":", 0);
1110 hostname
= g_strdup(tmp
[0]);
1111 if (tmp
[1]) port
= strtoul(tmp
[1], NULL
, 10);
1115 tmp
= g_strsplit(parts
[i
], "=", 0);
1117 if (g_ascii_strcasecmp("transport", tmp
[0]) == 0) {
1118 if (g_ascii_strcasecmp("tcp", tmp
[1]) == 0) {
1119 transport_type
= SIPE_TRANSPORT_TCP
;
1128 /* Close old connection */
1129 sipe_core_connection_cleanup(sipe_private
);
1130 /* transport and sipe_private->transport are invalid after this */
1132 /* Create new connection */
1133 sipe_server_register(sipe_private
, transport_type
, hostname
, port
);
1134 /* sipe_private->transport has a new value */
1135 SIPE_DEBUG_INFO("process_register_response: redirected to host %s port %d transport %d",
1136 hostname
, port
, transport_type
);
1143 const char *auth_hdr
;
1145 SIPE_DEBUG_INFO("process_register_response: REGISTER retries %d", transport
->registrar
.retries
);
1147 if (transport
->reauthenticate_set
) {
1148 SIPE_DEBUG_ERROR_NOFORMAT("process_register_response: RE-REGISTER rejected, triggering re-authentication");
1149 do_reauthenticate_cb(sipe_private
, NULL
);
1153 if (sip_sec_context_is_ready(transport
->registrar
.gssapi_context
)) {
1154 SIPE_DEBUG_INFO_NOFORMAT("process_register_response: authentication handshake failed - giving up.");
1155 sipe_backend_connection_error(SIPE_CORE_PUBLIC
,
1156 SIPE_CONNECTION_ERROR_AUTHENTICATION_FAILED
,
1157 _("Authentication failed"));
1161 auth_hdr
= get_auth_header(sipe_private
, &transport
->registrar
, msg
);
1163 sipe_backend_connection_error(SIPE_CORE_PUBLIC
,
1164 SIPE_CONNECTION_ERROR_AUTHENTICATION_IMPOSSIBLE
,
1165 _("Incompatible authentication scheme chosen"));
1168 SIPE_DEBUG_INFO("process_register_response: Auth header: %s", auth_hdr
);
1169 fill_auth(auth_hdr
, &transport
->registrar
);
1170 transport
->reregister_set
= FALSE
;
1171 transport
->register_attempt
= 0;
1172 do_register(sipe_private
,
1173 sipe_backend_connection_is_disconnecting(SIPE_CORE_PUBLIC
));
1180 sipmsg_parse_warning(msg
, &reason
);
1181 reason
= reason
? reason
: sipmsg_get_ms_diagnostics_public_reason(msg
);
1182 warning
= g_strdup_printf(_("You have been rejected by the server: %s"),
1183 reason
? reason
: _("no reason given"));
1186 sipe_backend_connection_error(SIPE_CORE_PUBLIC
,
1187 SIPE_CONNECTION_ERROR_INVALID_SETTINGS
,
1195 const gchar
*diagnostics
= sipmsg_find_header(msg
, "ms-diagnostics");
1196 gchar
*reason
= sipmsg_get_ms_diagnostics_reason(msg
);
1198 warning
= g_strdup_printf(_("Not found: %s. Please contact your Administrator"),
1199 diagnostics
? (reason
? reason
: _("no reason given")) :
1200 _("SIP is either not enabled for the destination URI or it does not exist"));
1203 sipe_backend_connection_error(SIPE_CORE_PUBLIC
,
1204 SIPE_CONNECTION_ERROR_INVALID_USERNAME
,
1210 case 504: /* Server time-out */
1211 /* first attempt + 5 retries */
1212 if (transport
->register_attempt
< 6) {
1213 SIPE_DEBUG_INFO("process_register_response: RE-REGISTER timeout on attempt %d, retrying later",
1214 transport
->register_attempt
);
1215 sip_transport_set_reregister(sipe_private
, 60);
1221 gchar
*reason
= sipmsg_get_ms_diagnostics_reason(msg
);
1223 warning
= g_strdup_printf(_("Service unavailable: %s"), reason
? reason
: _("no reason given"));
1226 sipe_backend_connection_error(SIPE_CORE_PUBLIC
,
1227 SIPE_CONNECTION_ERROR_NETWORK
,
1237 static gboolean
register_response_timeout(struct sipe_core_private
*sipe_private
,
1238 SIPE_UNUSED_PARAMETER
struct sipmsg
*msg
,
1239 SIPE_UNUSED_PARAMETER
struct transaction
*trans
)
1241 struct sip_transport
*transport
= sipe_private
->transport
;
1242 if (transport
->register_attempt
< 6) {
1243 SIPE_DEBUG_INFO("register_response_timeout: no answer to attempt %d, retrying",
1244 transport
->register_attempt
);
1245 do_register(sipe_private
, FALSE
);
1247 gchar
*warning
= g_strdup_printf(_("Service unavailable: %s"), _("no reason given"));
1248 sipe_backend_connection_error(SIPE_CORE_PUBLIC
,
1249 SIPE_CONNECTION_ERROR_NETWORK
,
1256 static void do_register(struct sipe_core_private
*sipe_private
,
1257 gboolean deregister
)
1259 struct sip_transport
*transport
= sipe_private
->transport
;
1265 if (!sipe_private
->public.sip_domain
) return;
1268 if (transport
->reregister_set
) {
1269 transport
->reregister_set
= FALSE
;
1270 transport
->register_attempt
= 1;
1272 transport
->register_attempt
++;
1276 transport
->deregister
= deregister
;
1277 transport
->auth_incomplete
= FALSE
;
1279 uuid
= get_uuid(sipe_private
);
1280 hdr
= g_strdup_printf("Contact: <sip:%s:%d;transport=%s;ms-opaque=d3470f2e1d>;methods=\"INVITE, MESSAGE, INFO, SUBSCRIBE, OPTIONS, BYE, CANCEL, NOTIFY, ACK, REFER, BENOTIFY\";proxy=replace;+sip.instance=\"<urn:uuid:%s>\"\r\n"
1281 "Supported: gruu-10, adhoclist, msrtc-event-categories, com.microsoft.msrtc.presence\r\n"
1282 "Event: registration\r\n"
1283 "Allow-Events: presence\r\n"
1284 "ms-keep-alive: UAC;hop-hop=yes\r\n"
1286 sipe_backend_network_ip_address(SIPE_CORE_PUBLIC
),
1287 transport
->connection
->client_port
,
1288 TRANSPORT_DESCRIPTOR
,
1290 deregister
? "Expires: 0\r\n" : "");
1293 uri
= sip_uri_from_name(sipe_private
->public.sip_domain
);
1294 to
= sip_uri_self(sipe_private
);
1295 sip_transport_request_timeout(sipe_private
,
1302 process_register_response
,
1304 deregister
? NULL
: register_response_timeout
);
1310 /* Make sure that all messages are pushed to the server
1311 before the connection gets shut down */
1312 SIPE_DEBUG_INFO_NOFORMAT("De-register from server. Flushing outstanding messages.");
1313 sipe_backend_transport_flush(transport
->connection
);
1317 void sip_transport_deregister(struct sipe_core_private
*sipe_private
)
1319 do_register(sipe_private
, TRUE
);
1322 void sip_transport_disconnect(struct sipe_core_private
*sipe_private
)
1324 struct sip_transport
*transport
= sipe_private
->transport
;
1326 /* transport can be NULL during connection setup */
1328 sipe_backend_transport_disconnect(transport
->connection
);
1330 sipe_auth_free(&transport
->registrar
);
1331 sipe_auth_free(&transport
->proxy
);
1333 g_free(transport
->server_name
);
1334 g_free(transport
->server_version
);
1335 g_free(transport
->user_agent
);
1337 while (transport
->transactions
)
1338 transactions_remove(sipe_private
,
1339 transport
->transactions
->data
);
1344 sipe_private
->transport
= NULL
;
1345 sipe_private
->service_data
= NULL
;
1346 sipe_private
->address_data
= NULL
;
1348 if (sipe_private
->dns_query
)
1349 sipe_backend_dns_query_cancel(sipe_private
->dns_query
);
1353 void sip_transport_authentication_completed(struct sipe_core_private
*sipe_private
)
1355 do_reauthenticate_cb(sipe_private
, NULL
);
1358 guint
sip_transport_port(struct sipe_core_private
*sipe_private
)
1360 return sipe_private
->transport
->server_port
;
1363 static void process_input_message(struct sipe_core_private
*sipe_private
,
1366 struct sip_transport
*transport
= sipe_private
->transport
;
1367 gboolean notfound
= FALSE
;
1368 const char *method
= msg
->method
? msg
->method
: "NOT FOUND";
1370 SIPE_DEBUG_INFO("process_input_message: msg->response(%d),msg->method(%s)",
1371 msg
->response
, method
);
1373 if (msg
->response
== 0) { /* request */
1374 if (sipe_strequal(method
, "MESSAGE")) {
1375 process_incoming_message(sipe_private
, msg
);
1376 } else if (sipe_strequal(method
, "NOTIFY")) {
1377 SIPE_DEBUG_INFO_NOFORMAT("send->process_incoming_notify");
1378 process_incoming_notify(sipe_private
, msg
);
1379 sip_transport_response(sipe_private
, msg
, 200, "OK", NULL
);
1380 } else if (sipe_strequal(method
, "BENOTIFY")) {
1381 SIPE_DEBUG_INFO_NOFORMAT("send->process_incoming_benotify");
1382 process_incoming_notify(sipe_private
, msg
);
1383 } else if (sipe_strequal(method
, "INVITE")) {
1384 process_incoming_invite(sipe_private
, msg
);
1385 } else if (sipe_strequal(method
, "REFER")) {
1386 process_incoming_refer(sipe_private
, msg
);
1387 } else if (sipe_strequal(method
, "OPTIONS")) {
1388 process_incoming_options(sipe_private
, msg
);
1389 } else if (sipe_strequal(method
, "INFO")) {
1390 process_incoming_info(sipe_private
, msg
);
1391 } else if (sipe_strequal(method
, "ACK")) {
1392 /* ACK's don't need any response */
1393 } else if (sipe_strequal(method
, "PRACK")) {
1394 sip_transport_response(sipe_private
, msg
, 200, "OK", NULL
);
1395 } else if (sipe_strequal(method
, "SUBSCRIBE")) {
1396 /* LCS 2005 sends us these - just respond 200 OK */
1397 sip_transport_response(sipe_private
, msg
, 200, "OK", NULL
);
1398 } else if (sipe_strequal(method
, "CANCEL")) {
1399 process_incoming_cancel(sipe_private
, msg
);
1400 } else if (sipe_strequal(method
, "BYE")) {
1401 process_incoming_bye(sipe_private
, msg
);
1403 sip_transport_response(sipe_private
, msg
, 501, "Not implemented", NULL
);
1407 } else { /* response */
1408 struct transaction
*trans
= transactions_find(transport
, msg
);
1410 if (msg
->response
< 200) {
1411 /* ignore provisional response */
1412 SIPE_DEBUG_INFO("process_input_message: got provisional (%d) response, ignoring", msg
->response
);
1414 /* Transaction not yet completed */
1417 } else if (msg
->response
== 401) { /* Unauthorized */
1419 if (sipe_strequal(trans
->msg
->method
, "REGISTER")) {
1420 /* Expected response during authentication handshake */
1421 transport
->registrar
.retries
++;
1422 SIPE_DEBUG_INFO("process_input_message: RE-REGISTER CSeq: %d", transport
->cseq
);
1426 /* Are we registered? */
1427 if (transport
->reregister_set
) {
1428 SIPE_DEBUG_INFO_NOFORMAT("process_input_message: 401 response to non-REGISTER message. Retrying with new authentication.");
1429 sipmsg_remove_header_now(trans
->msg
, "Authorization");
1430 sign_outgoing_message(sipe_private
,
1434 * We don't have a valid authentication at the moment.
1435 * Resend message unchanged. It will be rejected again
1436 * and hopefully by then we have a valid authentication.
1438 SIPE_DEBUG_INFO_NOFORMAT("process_input_message: 401 response to non-REGISTER message. Bouncing...");
1441 /* Resend request */
1442 resend
= sipmsg_to_string(trans
->msg
);
1443 sipe_utils_message_debug("SIP", resend
, NULL
, TRUE
);
1444 sipe_backend_transport_message(sipe_private
->transport
->connection
, resend
);
1447 /* Transaction not yet completed */
1451 } else if (msg
->response
== 407) { /* Proxy Authentication Required */
1453 if (transport
->proxy
.retries
++ <= 30) {
1454 const gchar
*proxy_hdr
= sipmsg_find_header(msg
, "Proxy-Authenticate");
1459 if (!g_ascii_strncasecmp(proxy_hdr
, "Digest", 6)) {
1460 auth
= sip_sec_digest_authorization(sipe_private
,
1467 transport
->proxy
.type
= SIPE_AUTHENTICATION_TYPE_UNSET
;
1468 for (i
= 0; i
< AUTH_PROTOCOLS
; i
++) {
1469 const gchar
*protocol
= auth_type_to_protocol
[i
];
1471 !g_ascii_strncasecmp(proxy_hdr
, protocol
, strlen(protocol
))) {
1472 SIPE_DEBUG_INFO("process_input_message: proxy authentication scheme '%s'", protocol
);
1473 transport
->proxy
.type
= i
;
1474 transport
->proxy
.protocol
= protocol
;
1475 fill_auth(proxy_hdr
, &transport
->proxy
);
1476 auth
= auth_header(sipe_private
, &transport
->proxy
, trans
->msg
);
1485 /* replace old proxy authentication with new one */
1486 sipmsg_remove_header_now(trans
->msg
, "Proxy-Authorization");
1487 sipmsg_add_header_now(trans
->msg
, "Proxy-Authorization", auth
);
1490 /* resend request with proxy authentication */
1491 resend
= sipmsg_to_string(trans
->msg
);
1492 sipe_utils_message_debug("SIP", resend
, NULL
, TRUE
);
1493 sipe_backend_transport_message(sipe_private
->transport
->connection
, resend
);
1496 /* Transaction not yet completed */
1500 SIPE_DEBUG_ERROR_NOFORMAT("process_input_message: can't generate proxy authentication. Giving up.");
1502 SIPE_DEBUG_ERROR_NOFORMAT("process_input_message: 407 response without 'Proxy-Authenticate' header. Giving up.");
1504 SIPE_DEBUG_ERROR_NOFORMAT("process_input_message: too many proxy authentication retries. Giving up.");
1507 transport
->registrar
.retries
= 0;
1508 transport
->proxy
.retries
= 0;
1511 /* Is transaction completed? */
1513 if (trans
->callback
) {
1514 SIPE_DEBUG_INFO_NOFORMAT("process_input_message: we have a transaction callback");
1515 /* call the callback to process response */
1516 (trans
->callback
)(sipe_private
, msg
, trans
);
1517 /* transport && trans no longer valid after redirect */
1521 * Redirect case: sipe_private->transport is
1522 * the new transport with empty queue
1524 if (sipe_private
->transport
->transactions
) {
1525 SIPE_DEBUG_INFO("process_input_message: removing CSeq %d", transport
->cseq
);
1526 transactions_remove(sipe_private
, trans
);
1530 SIPE_DEBUG_INFO_NOFORMAT("process_input_message: received response to unknown transaction");
1536 SIPE_DEBUG_INFO("received a unknown sip message with method %s and response %d", method
, msg
->response
);
1540 static void sip_transport_input(struct sipe_transport_connection
*conn
)
1542 struct sipe_core_private
*sipe_private
= conn
->user_data
;
1543 struct sip_transport
*transport
= sipe_private
->transport
;
1544 gchar
*cur
= conn
->buffer
;
1546 /* according to the RFC remove CRLF at the beginning */
1547 while (*cur
== '\r' || *cur
== '\n') {
1550 if (cur
!= conn
->buffer
)
1551 sipe_utils_shrink_buffer(conn
, cur
);
1553 /* Received a full Header? */
1554 transport
->processing_input
= TRUE
;
1555 while (transport
->processing_input
&&
1556 ((cur
= strstr(conn
->buffer
, "\r\n\r\n")) != NULL
)) {
1562 msg
= sipmsg_parse_header(conn
->buffer
);
1565 remainder
= conn
->buffer_used
- (cur
- conn
->buffer
);
1566 if (msg
&& remainder
>= (guint
) msg
->bodylen
) {
1567 char *dummy
= g_malloc(msg
->bodylen
+ 1);
1568 memcpy(dummy
, cur
, msg
->bodylen
);
1569 dummy
[msg
->bodylen
] = '\0';
1571 cur
+= msg
->bodylen
;
1572 sipe_utils_message_debug("SIP",
1576 sipe_utils_shrink_buffer(conn
, cur
);
1579 SIPE_DEBUG_INFO("sipe_transport_input: body too short (%d < %d, strlen %d) - ignoring message", remainder
, msg
->bodylen
, (int)strlen(conn
->buffer
));
1583 /* restore header for next try */
1588 // Verify the signature before processing it
1589 if (sip_sec_context_is_ready(transport
->registrar
.gssapi_context
)) {
1590 struct sipmsg_breakdown msgbd
;
1591 gchar
*signature_input_str
;
1594 sipmsg_breakdown_parse(&msgbd
, transport
->registrar
.realm
, transport
->registrar
.target
,
1595 transport
->registrar
.protocol
);
1596 signature_input_str
= sipmsg_breakdown_get_string(transport
->registrar
.version
, &msgbd
);
1598 rspauth
= sipmsg_find_part_of_header(sipmsg_find_header(msg
, "Authentication-Info"), "rspauth=\"", "\"", NULL
);
1600 if (rspauth
!= NULL
) {
1601 if (sip_sec_verify_signature(transport
->registrar
.gssapi_context
, signature_input_str
, rspauth
)) {
1602 SIPE_DEBUG_INFO_NOFORMAT("sip_transport_input: signature of incoming message validated");
1603 process_input_message(sipe_private
, msg
);
1604 /* transport is invalid after redirect */
1606 SIPE_DEBUG_INFO_NOFORMAT("sip_transport_input: signature of incoming message is invalid.");
1607 sipe_backend_connection_error(SIPE_CORE_PUBLIC
,
1608 SIPE_CONNECTION_ERROR_NETWORK
,
1609 _("Invalid message signature received"));
1611 } else if ((msg
->response
== 401) ||
1612 sipe_strequal(msg
->method
, "REGISTER")) {
1613 /* a) Retry non-REGISTER requests with updated authentication */
1614 /* b) We must always process REGISTER responses */
1615 process_input_message(sipe_private
, msg
);
1617 /* OCS sends provisional messages that are *not* signed */
1618 if (msg
->response
>= 200) {
1619 /* We are not calling process_input_message(),
1620 so we need to drop the transaction here. */
1621 struct transaction
*trans
= transactions_find(transport
, msg
);
1622 if (trans
) transactions_remove(sipe_private
, trans
);
1624 SIPE_DEBUG_INFO_NOFORMAT("sip_transport_input: message without authentication data - ignoring");
1626 g_free(signature_input_str
);
1629 sipmsg_breakdown_free(&msgbd
);
1631 process_input_message(sipe_private
, msg
);
1636 /* Redirect: old content of "transport" & "conn" is no longer valid */
1637 transport
= sipe_private
->transport
;
1638 conn
= transport
->connection
;
1642 static void sip_transport_connected(struct sipe_transport_connection
*conn
)
1644 struct sipe_core_private
*sipe_private
= conn
->user_data
;
1645 sipe_private
->service_data
= NULL
;
1646 sipe_private
->address_data
= NULL
;
1647 do_register(sipe_private
, FALSE
);
1650 static void resolve_next_service(struct sipe_core_private
*sipe_private
,
1651 const struct sip_service_data
*start
);
1652 static void resolve_next_address(struct sipe_core_private
*sipe_private
,
1654 static void sip_transport_error(struct sipe_transport_connection
*conn
,
1657 struct sipe_core_private
*sipe_private
= conn
->user_data
;
1659 /* This failed attempt was based on a DNS SRV record */
1660 if (sipe_private
->service_data
) {
1661 resolve_next_service(sipe_private
, NULL
);
1662 /* This failed attempt was based on a DNS A record */
1663 } else if (sipe_private
->address_data
) {
1664 resolve_next_address(sipe_private
, FALSE
);
1666 sipe_backend_connection_error(SIPE_CORE_PUBLIC
,
1667 SIPE_CONNECTION_ERROR_NETWORK
,
1672 /* server_name must be g_alloc()'ed */
1673 static void sipe_server_register(struct sipe_core_private
*sipe_private
,
1678 sipe_connect_setup setup
= {
1681 (server_port
!= 0) ? server_port
:
1682 (type
== SIPE_TRANSPORT_TLS
) ? 5061 : 5060,
1684 sip_transport_connected
,
1685 sip_transport_input
,
1688 struct sip_transport
*transport
= g_new0(struct sip_transport
, 1);
1690 transport
->server_name
= server_name
;
1691 transport
->server_port
= setup
.server_port
;
1692 transport
->connection
= sipe_backend_transport_connect(SIPE_CORE_PUBLIC
,
1694 sipe_private
->transport
= transport
;
1697 struct sip_service_data
{
1698 const char *protocol
;
1699 const char *transport
;
1704 * Autodiscover using DNS SRV records. See RFC2782/3263
1706 * Service list for AUTO
1708 static const struct sip_service_data service_autodetect
[] = {
1709 { "sipinternaltls", "tcp", SIPE_TRANSPORT_TLS
}, /* for internal TLS connections */
1710 { "sipinternal", "tcp", SIPE_TRANSPORT_TCP
}, /* for internal TCP connections */
1711 { "sip", "tls", SIPE_TRANSPORT_TLS
}, /* for external TLS connections */
1712 { "sip", "tcp", SIPE_TRANSPORT_TCP
}, /*.for external TCP connections */
1716 /* Service list for SSL/TLS */
1717 static const struct sip_service_data service_tls
[] = {
1718 { "sipinternaltls", "tcp", SIPE_TRANSPORT_TLS
}, /* for internal TLS connections */
1719 { "sip", "tls", SIPE_TRANSPORT_TLS
}, /* for external TLS connections */
1723 /* Service list for TCP */
1724 static const struct sip_service_data service_tcp
[] = {
1725 { "sipinternal", "tcp", SIPE_TRANSPORT_TCP
}, /* for internal TCP connections */
1726 { "sip", "tcp", SIPE_TRANSPORT_TCP
}, /*.for external TCP connections */
1730 static const struct sip_service_data
*services
[] = {
1731 service_autodetect
, /* SIPE_TRANSPORT_AUTO */
1732 service_tls
, /* SIPE_TRANSPORT_TLS */
1733 service_tcp
/* SIPE_TRANSPORT_TCP */
1736 struct sip_address_data
{
1742 * Autodiscover using DNS A records. This is an extension addded
1743 * by Microsoft. See http://support.microsoft.com/kb/2619522
1745 static const struct sip_address_data addresses
[] = {
1746 { "sipinternal", 5061 },
1747 { "sipexternal", 443 },
1749 * Our implementation supports only one port per host name. If the host name
1750 * resolves OK, we abort the search and try to connect. If we would know if we
1751 * are trying to connect from "Intranet" or "Internet" then we could choose
1752 * between those two ports.
1754 * We drop port 5061 in order to cover the "Internet" case.
1762 static void sipe_core_dns_resolved(struct sipe_core_public
*sipe_public
,
1763 const gchar
*hostname
, guint port
)
1765 struct sipe_core_private
*sipe_private
= SIPE_CORE_PRIVATE
;
1766 gboolean service
= sipe_private
->service_data
!= NULL
;
1768 sipe_private
->dns_query
= NULL
;
1775 host
= g_strdup(hostname
);
1776 type
= sipe_private
->service_data
->type
;
1778 /* DNS A resolver returns an IP address */
1779 host
= g_strdup_printf("%s.%s",
1780 sipe_private
->address_data
->prefix
,
1781 sipe_private
->public.sip_domain
);
1782 port
= sipe_private
->address_data
->port
;
1783 type
= sipe_private
->transport_type
;
1784 if (type
== SIPE_TRANSPORT_AUTO
)
1785 type
= SIPE_TRANSPORT_TLS
;
1788 SIPE_DEBUG_INFO("sipe_core_dns_resolved - %s hostname: %s port: %d",
1789 service
? "SRV" : "A", hostname
, port
);
1790 sipe_server_register(sipe_private
, type
, host
, port
);
1793 resolve_next_service(SIPE_CORE_PRIVATE
, NULL
);
1795 resolve_next_address(SIPE_CORE_PRIVATE
, FALSE
);
1799 static void resolve_next_service(struct sipe_core_private
*sipe_private
,
1800 const struct sip_service_data
*start
)
1803 sipe_private
->service_data
= start
;
1805 sipe_private
->service_data
++;
1806 if (sipe_private
->service_data
->protocol
== NULL
) {
1808 /* We tried all services */
1809 sipe_private
->service_data
= NULL
;
1811 /* Try A records list next */
1812 SIPE_DEBUG_INFO_NOFORMAT("no SRV records found; trying A records next");
1813 resolve_next_address(sipe_private
, TRUE
);
1818 /* Try to resolve next service */
1819 sipe_private
->dns_query
= sipe_backend_dns_query_srv(
1821 sipe_private
->service_data
->protocol
,
1822 sipe_private
->service_data
->transport
,
1823 sipe_private
->public.sip_domain
,
1824 (sipe_dns_resolved_cb
) sipe_core_dns_resolved
,
1828 static void resolve_next_address(struct sipe_core_private
*sipe_private
,
1834 sipe_private
->address_data
= addresses
;
1836 sipe_private
->address_data
++;
1837 if (sipe_private
->address_data
->prefix
== NULL
) {
1838 guint type
= sipe_private
->transport_type
;
1840 /* We tried all addresss */
1841 sipe_private
->address_data
= NULL
;
1843 /* Try connecting to the SIP hostname directly */
1844 SIPE_DEBUG_INFO_NOFORMAT("no SRV or A records found; using SIP domain as fallback");
1845 if (type
== SIPE_TRANSPORT_AUTO
)
1846 type
= SIPE_TRANSPORT_TLS
;
1848 sipe_server_register(sipe_private
, type
,
1849 g_strdup(sipe_private
->public.sip_domain
),
1855 /* Try to resolve next address */
1856 hostname
= g_strdup_printf("%s.%s",
1857 sipe_private
->address_data
->prefix
,
1858 sipe_private
->public.sip_domain
);
1859 sipe_private
->dns_query
= sipe_backend_dns_query_a(
1862 sipe_private
->address_data
->port
,
1863 (sipe_dns_resolved_cb
) sipe_core_dns_resolved
,
1869 * NOTE: this function can be called before sipe_core_allocate()!
1871 gboolean
sipe_core_transport_sip_requires_password(guint authentication
,
1874 return(sip_sec_requires_password(authentication
, sso
));
1877 void sipe_core_transport_sip_connect(struct sipe_core_public
*sipe_public
,
1879 guint authentication
,
1880 const gchar
*server
,
1883 struct sipe_core_private
*sipe_private
= SIPE_CORE_PRIVATE
;
1885 /* backend initialization is complete */
1886 sipe_core_backend_initialized(sipe_private
, authentication
);
1889 * Initializing the certificate sub-system will trigger the generation
1890 * of a cryptographic key pair which takes time. If we do this after we
1891 * have connected to the server then there is a risk that we run into a
1892 * SIP connection timeout. So let's get this out of the way now...
1894 * This is currently only needed if the user has selected TLS-DSK.
1896 if (sipe_private
->authentication_type
== SIPE_AUTHENTICATION_TYPE_TLS_DSK
)
1897 sipe_certificate_init(sipe_private
);
1900 /* Use user specified server[:port] */
1901 int port_number
= 0;
1904 port_number
= atoi(port
);
1906 SIPE_DEBUG_INFO("sipe_core_connect: user specified SIP server %s:%d",
1907 server
, port_number
);
1909 sipe_server_register(sipe_private
, transport
,
1910 g_strdup(server
), port_number
);
1912 /* Server auto-discovery */
1914 /* Remember user specified transport type */
1915 sipe_private
->transport_type
= transport
;
1916 resolve_next_service(sipe_private
, services
[transport
]);
1920 void sipe_core_transport_sip_keepalive(struct sipe_core_public
*sipe_public
)
1922 SIPE_DEBUG_INFO("sending keep alive %d",
1923 sipe_public
->keepalive_timeout
);
1924 sipe_utils_message_debug("SIP", "", NULL
, TRUE
);
1925 sipe_backend_transport_message(SIPE_CORE_PRIVATE
->transport
->connection
,
1929 const gchar
*sipe_core_transport_sip_server_name(struct sipe_core_public
*sipe_public
)
1931 struct sip_transport
*transport
= SIPE_CORE_PRIVATE
->transport
;
1932 return(transport
? transport
->server_name
: NULL
);
1935 int sip_transaction_cseq(struct transaction
*trans
)
1939 g_return_val_if_fail(trans
&& trans
->key
, 0);
1941 sscanf(trans
->key
, "<%*[a-zA-Z0-9]><%d INVITE>", &cseq
);