2 * @file sip-transport.c
6 * Copyright (C) 2010-2018 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.
49 * Specification references:
51 * - [MS-SIPAE]: http://msdn.microsoft.com/en-us/library/cc431510.aspx
52 * - RFC2732: http://www.ietf.org/rfc/rfc2732.txt
65 #include "sipe-common.h"
68 #include "sip-sec-digest.h"
69 #include "sip-transport.h"
70 #include "sipe-backend.h"
71 #include "sipe-core.h"
72 #include "sipe-core-private.h"
73 #include "sipe-certificate.h"
74 #include "sipe-dialog.h"
75 #include "sipe-incoming.h"
76 #include "sipe-lync-autodiscover.h"
78 #include "sipe-notify.h"
79 #include "sipe-schedule.h"
80 #include "sipe-sign.h"
81 #include "sipe-subscriptions.h"
82 #include "sipe-utils.h"
87 struct sip_sec_context
*gssapi_context
;
90 const gchar
*protocol
;
101 /* sip-transport.c private data */
102 struct sip_transport
{
103 struct sipe_transport_connection
*connection
;
109 /* local IP address of transport socket */
110 gchar
*ip_address
; /* RAW X.X.X.X (IPv4), X:X:...:X (IPv6) */
111 gchar
*uri_address
; /* URI X.X.X.X (IPv4), [X:X:...:X] (IPv6) */
112 const gchar
*sdp_marker
; /* SDP address marker: "IP4" or "IP6" */
114 GSList
*transactions
;
116 struct sip_auth registrar
;
117 struct sip_auth proxy
;
120 guint register_attempt
;
122 guint keepalive_timeout
;
125 gboolean processing_input
; /* whether full header received */
126 gboolean auth_incomplete
; /* whether authentication not completed */
127 gboolean auth_retry
; /* whether next authentication should be tried */
128 gboolean reregister_set
; /* whether reregister timer set */
129 gboolean reauthenticate_set
; /* whether reauthenticate timer set */
130 gboolean subscribed
; /* whether subscribed to events, except buddies presence */
131 gboolean deregister
; /* whether in deregistration */
134 /* Keep in sync with sipe_transport_type! */
135 static const char *transport_descriptor
[] = { "", "tls", "tcp"};
136 #define TRANSPORT_DESCRIPTOR (transport_descriptor[transport->connection->type])
138 static char *genbranch()
140 return g_strdup_printf("z9hG4bK%04X%04X%04X%04X%04X",
141 rand() & 0xFFFF, rand() & 0xFFFF, rand() & 0xFFFF,
142 rand() & 0xFFFF, rand() & 0xFFFF);
145 static void sipe_auth_free(struct sip_auth
*auth
)
147 g_free(auth
->opaque
);
149 auth
->protocol
= NULL
;
152 g_free(auth
->sts_uri
);
153 auth
->sts_uri
= NULL
;
154 g_free(auth
->target
);
157 auth
->type
= SIPE_AUTHENTICATION_TYPE_UNSET
;
160 auth
->can_retry
= FALSE
;
161 g_free(auth
->gssapi_data
);
162 auth
->gssapi_data
= NULL
;
163 sip_sec_destroy_context(auth
->gssapi_context
);
164 auth
->gssapi_context
= NULL
;
167 static void sipe_make_signature(struct sipe_core_private
*sipe_private
,
170 struct sip_transport
*transport
= sipe_private
->transport
;
171 if (sip_sec_context_is_ready(transport
->registrar
.gssapi_context
)) {
172 struct sipmsg_breakdown msgbd
;
173 gchar
*signature_input_str
;
175 sipmsg_breakdown_parse(&msgbd
, transport
->registrar
.realm
, transport
->registrar
.target
,
176 transport
->registrar
.protocol
);
177 msgbd
.rand
= g_strdup_printf("%08x", g_random_int());
178 transport
->registrar
.ntlm_num
++;
179 msgbd
.num
= g_strdup_printf("%d", transport
->registrar
.ntlm_num
);
180 signature_input_str
= sipmsg_breakdown_get_string(transport
->registrar
.version
, &msgbd
);
181 if (signature_input_str
!= NULL
) {
182 char *signature_hex
= sip_sec_make_signature(transport
->registrar
.gssapi_context
, signature_input_str
);
183 g_free(msg
->signature
);
184 msg
->signature
= signature_hex
;
186 msg
->rand
= g_strdup(msgbd
.rand
);
188 msg
->num
= g_strdup(msgbd
.num
);
189 g_free(signature_input_str
);
191 sipmsg_breakdown_free(&msgbd
);
195 static const gchar
*const auth_type_to_protocol
[] = {
196 NULL
, /* SIPE_AUTHENTICATION_TYPE_UNSET */
197 NULL
, /* SIPE_AUTHENTICATION_TYPE_BASIC */
198 "NTLM", /* SIPE_AUTHENTICATION_TYPE_NTLM */
199 "Kerberos", /* SIPE_AUTHENTICATION_TYPE_KERBEROS */
200 NULL
, /* SIPE_AUTHENTICATION_TYPE_NEGOTIATE */
201 "TLS-DSK", /* SIPE_AUTHENTICATION_TYPE_TLS_DSK */
202 NULL
, /* SIPE_AUTHENTICATION_TYPE_AUTOMATIC */
204 #define AUTH_PROTOCOLS (sizeof(auth_type_to_protocol)/sizeof(gchar *))
206 static gchar
*msg_signature_to_auth(struct sip_auth
*auth
,
209 return(g_strdup_printf("%s qop=\"auth\", opaque=\"%s\", realm=\"%s\", targetname=\"%s\", crand=\"%s\", cnum=\"%s\", response=\"%s\"",
211 auth
->opaque
, auth
->realm
, auth
->target
,
212 msg
->rand
, msg
->num
, msg
->signature
));
215 static gboolean
auth_can_retry(struct sip_transport
*transport
,
216 const struct sip_auth
*auth
)
218 /* NTLM is the scheme with lowest priority - don't retry */
221 (auth
->type
!= SIPE_AUTHENTICATION_TYPE_NTLM
);
223 transport
->auth_retry
= TRUE
;
227 static void initialize_auth_retry(struct sipe_core_private
*sipe_private
,
228 struct sip_auth
*auth
)
230 struct sip_transport
*transport
= sipe_private
->transport
;
232 if (auth_can_retry(transport
, auth
)) {
233 if (auth
->gssapi_context
) {
234 /* need to drop context for retry */
235 sip_sec_destroy_context(auth
->gssapi_context
);
236 auth
->gssapi_context
= NULL
;
239 sipe_backend_connection_error(SIPE_CORE_PUBLIC
,
240 SIPE_CONNECTION_ERROR_AUTHENTICATION_FAILED
,
241 _("Failed to authenticate to server"));
245 static gchar
*initialize_auth_context(struct sipe_core_private
*sipe_private
,
246 struct sip_auth
*auth
,
249 struct sip_transport
*transport
= sipe_private
->transport
;
251 gchar
*gssapi_data
= NULL
;
258 * If transport is de-registering when we reach this point then we
259 * are in the middle of the previous authentication context setup
260 * attempt. So we shouldn't try another attempt.
262 if (transport
->deregister
)
265 /* Create security context or handshake continuation? */
266 if (auth
->gssapi_context
) {
267 /* Perform next step in authentication handshake */
268 gboolean status
= sip_sec_init_context_step(auth
->gssapi_context
,
274 /* If authentication is completed gssapi_data can be NULL */
276 (sip_sec_context_is_ready(auth
->gssapi_context
) || gssapi_data
))) {
277 SIPE_DEBUG_ERROR_NOFORMAT("initialize_auth_context: security context continuation failed");
279 initialize_auth_retry(sipe_private
, auth
);
284 /* Create security context */
285 gpointer password
= sipe_private
->password
;
287 /* For TLS-DSK the "password" is a certificate */
288 if (auth
->type
== SIPE_AUTHENTICATION_TYPE_TLS_DSK
) {
289 password
= sipe_certificate_tls_dsk_find(sipe_private
,
294 SIPE_DEBUG_INFO("initialize_auth_context: TLS-DSK Certificate Provisioning URI %s",
296 if (!sipe_certificate_tls_dsk_generate(sipe_private
,
299 gchar
*tmp
= g_strdup_printf(_("Can't request certificate from %s"),
301 sipe_backend_connection_error(SIPE_CORE_PUBLIC
,
302 SIPE_CONNECTION_ERROR_AUTHENTICATION_FAILED
,
307 sipe_backend_connection_error(SIPE_CORE_PUBLIC
,
308 SIPE_CONNECTION_ERROR_AUTHENTICATION_FAILED
,
309 _("No URI for certificate provisioning service provided"));
312 /* we can't authenticate the message yet */
313 transport
->auth_incomplete
= TRUE
;
317 SIPE_DEBUG_INFO("initialize_auth_context: TLS-DSK certificate for target '%s' found.",
322 auth
->gssapi_context
= sip_sec_create_context(auth
->type
,
323 SIPE_CORE_PRIVATE_FLAG_IS(SSO
),
324 FALSE
, /* connection-less for SIP */
325 sipe_private
->authuser
,
328 if (auth
->gssapi_context
) {
329 sip_sec_init_context_step(auth
->gssapi_context
,
336 /* if auth->gssapi_context is NULL then gssapi_data is still NULL */
338 SIPE_DEBUG_ERROR_NOFORMAT("initialize_auth_context: security context initialization failed");
339 initialize_auth_retry(sipe_private
, auth
);
344 if ((auth
->version
> 3) &&
345 sip_sec_context_is_ready(auth
->gssapi_context
)) {
346 sipe_make_signature(sipe_private
, msg
);
347 sign_str
= g_strdup_printf(", crand=\"%s\", cnum=\"%s\", response=\"%s\"",
348 msg
->rand
, msg
->num
, msg
->signature
);
350 sign_str
= g_strdup("");
354 gssapi_str
= g_strdup_printf(", gssapi-data=\"%s\"",
358 gssapi_str
= g_strdup("");
361 opaque_str
= auth
->opaque
? g_strdup_printf(", opaque=\"%s\"", auth
->opaque
) : g_strdup("");
363 if (auth
->version
> 2) {
364 version_str
= g_strdup_printf(", version=%d", auth
->version
);
366 version_str
= g_strdup("");
369 ret
= g_strdup_printf("%s qop=\"auth\"%s, realm=\"%s\", targetname=\"%s\"%s%s%s",
370 auth
->protocol
, opaque_str
,
371 auth
->realm
, auth
->target
,
372 gssapi_str
, version_str
, sign_str
);
381 static gchar
*auth_header(struct sipe_core_private
*sipe_private
,
382 struct sip_auth
*auth
,
388 * If the message is already signed then we have an authentication
389 * context, i.e. the authentication handshake is complete. Generate
390 * authentication header from message signature.
392 if (msg
->signature
) {
393 ret
= msg_signature_to_auth(auth
, msg
);
396 * We should reach this point only when the authentication context
397 * needs to be initialized.
400 ret
= initialize_auth_context(sipe_private
, auth
, msg
);
406 static void fill_auth(const gchar
*hdr
, struct sip_auth
*auth
)
410 /* skip authentication identifier */
411 hdr
= strchr(hdr
, ' ');
413 SIPE_DEBUG_ERROR_NOFORMAT("fill_auth: corrupted authentication header");
419 /* start of next parameter value */
420 while ((param
= strchr(hdr
, '=')) != NULL
) {
423 /* parameter value type */
426 /* string: xyz="..."(,) */
427 end
= strchr(++param
, '"');
429 SIPE_DEBUG_ERROR("fill_auth: corrupted string parameter near '%s'", hdr
);
433 /* number: xyz=12345(,) */
434 end
= strchr(param
, ',');
437 end
= param
+ strlen(param
);
442 SIPE_DEBUG_INFO("fill_auth: hdr '%s'", hdr
);
443 SIPE_DEBUG_INFO("fill_auth: param '%s'", param
);
444 SIPE_DEBUG_INFO("fill_auth: end '%s'", end
);
448 if (g_str_has_prefix(hdr
, "gssapi-data=\"")) {
449 g_free(auth
->gssapi_data
);
450 auth
->gssapi_data
= g_strndup(param
, end
- param
);
451 } else if (g_str_has_prefix(hdr
, "opaque=\"")) {
452 g_free(auth
->opaque
);
453 auth
->opaque
= g_strndup(param
, end
- param
);
454 } else if (g_str_has_prefix(hdr
, "realm=\"")) {
456 auth
->realm
= g_strndup(param
, end
- param
);
457 } else if (g_str_has_prefix(hdr
, "sts-uri=\"")) {
458 /* Only used with SIPE_AUTHENTICATION_TYPE_TLS_DSK */
459 g_free(auth
->sts_uri
);
460 auth
->sts_uri
= g_strndup(param
, end
- param
);
461 } else if (g_str_has_prefix(hdr
, "targetname=\"")) {
462 g_free(auth
->target
);
463 auth
->target
= g_strndup(param
, end
- param
);
464 } else if (g_str_has_prefix(hdr
, "version=")) {
465 auth
->version
= atoi(param
);
468 /* skip to next parameter */
469 while ((*end
== '"') || (*end
== ',') || (*end
== ' '))
477 static void sign_outgoing_message(struct sipe_core_private
*sipe_private
,
480 struct sip_transport
*transport
= sipe_private
->transport
;
483 if (transport
->registrar
.type
== SIPE_AUTHENTICATION_TYPE_UNSET
) {
487 sipe_make_signature(sipe_private
, msg
);
489 buf
= auth_header(sipe_private
, &transport
->registrar
, msg
);
491 sipmsg_add_header_now(msg
, "Authorization", buf
);
497 * NOTE: Do *NOT* call sipe_backend_transport_message(...) directly!
499 * All SIP messages must pass through this function in order to update
500 * the timestamp for keepalive tracking.
502 static void send_sip_message(struct sip_transport
*transport
,
505 sipe_utils_message_debug(transport
->connection
, "SIP", string
, NULL
, TRUE
);
506 transport
->last_message
= time(NULL
);
507 sipe_backend_transport_message(transport
->connection
, string
);
510 static void start_keepalive_timer(struct sipe_core_private
*sipe_private
,
512 static void keepalive_timeout(struct sipe_core_private
*sipe_private
,
513 SIPE_UNUSED_PARAMETER gpointer data
)
515 struct sip_transport
*transport
= sipe_private
->transport
;
517 guint since_last
= time(NULL
) - transport
->last_message
;
518 guint restart
= transport
->keepalive_timeout
;
519 if (since_last
>= restart
) {
520 SIPE_DEBUG_INFO("keepalive_timeout: expired %d", restart
);
521 send_sip_message(transport
, "\r\n\r\n");
523 /* timeout not reached since last message -> reschedule */
524 restart
-= since_last
;
526 start_keepalive_timer(sipe_private
, restart
);
530 static void start_keepalive_timer(struct sipe_core_private
*sipe_private
,
533 sipe_schedule_seconds(sipe_private
,
534 "<+keepalive-timeout>",
541 void sip_transport_response(struct sipe_core_private
*sipe_private
,
549 GString
*outstr
= g_string_new("");
552 static const gchar
*keepers
[] = { "To", "From", "Call-ID", "CSeq", "Via", "Record-Route", NULL
};
554 /* Can return NULL! */
555 contact
= get_contact(sipe_private
);
557 sipmsg_add_header(msg
, "Contact", contact
);
562 gchar
*len
= g_strdup_printf("%" G_GSIZE_FORMAT
, (gsize
) strlen(body
));
563 sipmsg_add_header(msg
, "Content-Length", len
);
566 sipmsg_add_header(msg
, "Content-Length", "0");
569 sipmsg_add_header(msg
, "User-Agent", sipe_core_user_agent(sipe_private
));
571 msg
->response
= code
;
573 sipmsg_strip_headers(msg
, keepers
);
574 sipmsg_merge_new_headers(msg
);
575 sign_outgoing_message(sipe_private
, msg
);
577 g_string_append_printf(outstr
, "SIP/2.0 %d %s\r\n", code
, text
);
580 name
= ((struct sipnameval
*) (tmp
->data
))->name
;
581 value
= ((struct sipnameval
*) (tmp
->data
))->value
;
583 g_string_append_printf(outstr
, "%s: %s\r\n", name
, value
);
584 tmp
= g_slist_next(tmp
);
586 g_string_append_printf(outstr
, "\r\n%s", body
? body
: "");
587 send_sip_message(sipe_private
->transport
, outstr
->str
);
588 g_string_free(outstr
, TRUE
);
591 static void transactions_remove(struct sipe_core_private
*sipe_private
,
592 struct transaction
*trans
)
594 struct sip_transport
*transport
= sipe_private
->transport
;
595 if (transport
->transactions
) {
596 transport
->transactions
= g_slist_remove(transport
->transactions
,
598 SIPE_DEBUG_INFO("SIP transactions count:%d after removal", g_slist_length(transport
->transactions
));
600 if (trans
->msg
) sipmsg_free(trans
->msg
);
601 if (trans
->payload
) {
602 if (trans
->payload
->destroy
)
603 (*trans
->payload
->destroy
)(trans
->payload
->data
);
604 g_free(trans
->payload
);
607 if (trans
->timeout_key
) {
608 sipe_schedule_cancel(sipe_private
, trans
->timeout_key
);
609 g_free(trans
->timeout_key
);
615 static struct transaction
*transactions_find(struct sip_transport
*transport
,
618 GSList
*transactions
= transport
->transactions
;
619 const gchar
*call_id
= sipmsg_find_header(msg
, "Call-ID");
620 const gchar
*cseq
= sipmsg_find_header(msg
, "CSeq");
623 if (!call_id
|| !cseq
) {
624 SIPE_DEBUG_ERROR_NOFORMAT("transaction_find: no Call-ID or CSeq!");
628 key
= g_strdup_printf("<%s><%s>", call_id
, cseq
);
629 while (transactions
) {
630 struct transaction
*trans
= transactions
->data
;
631 if (!g_ascii_strcasecmp(trans
->key
, key
)) {
635 transactions
= transactions
->next
;
642 static void transaction_timeout_cb(struct sipe_core_private
*sipe_private
,
645 struct transaction
*trans
= data
;
646 (trans
->timeout_callback
)(sipe_private
, trans
->msg
, trans
);
647 transactions_remove(sipe_private
, trans
);
650 struct transaction
*sip_transport_request_timeout(struct sipe_core_private
*sipe_private
,
654 const gchar
*addheaders
,
656 struct sip_dialog
*dialog
,
657 TransCallback callback
,
659 TransCallback timeout_callback
)
661 struct sip_transport
*transport
= sipe_private
->transport
;
664 gchar
*ourtag
= dialog
&& dialog
->ourtag
? g_strdup(dialog
->ourtag
) : NULL
;
665 gchar
*theirtag
= dialog
&& dialog
->theirtag
? g_strdup(dialog
->theirtag
) : NULL
;
666 gchar
*theirepid
= dialog
&& dialog
->theirepid
? g_strdup(dialog
->theirepid
) : NULL
;
667 gchar
*callid
= dialog
&& dialog
->callid
? g_strdup(dialog
->callid
) : gencallid();
668 gchar
*branch
= dialog
&& dialog
->callid
? NULL
: genbranch();
669 gchar
*route
= g_strdup("");
670 const gchar
*epid
= transport
->epid
;
671 int cseq
= dialog
? ++dialog
->cseq
: 1 /* as Call-Id is new in this case */;
672 struct transaction
*trans
= NULL
;
674 if (dialog
&& dialog
->routes
)
676 GSList
*iter
= dialog
->routes
;
681 route
= g_strdup_printf("%sRoute: %s\r\n", route
, (char *)iter
->data
);
683 iter
= g_slist_next(iter
);
687 if (!ourtag
&& !dialog
) {
691 if (sipe_strequal(method
, "REGISTER")) {
692 if (sipe_private
->register_callid
) {
694 callid
= g_strdup(sipe_private
->register_callid
);
696 sipe_private
->register_callid
= g_strdup(callid
);
698 cseq
= ++transport
->cseq
;
701 buf
= g_strdup_printf("%s %s SIP/2.0\r\n"
702 "Via: SIP/2.0/%s %s:%d%s%s\r\n"
703 "From: <sip:%s>%s%s;epid=%s\r\n"
704 "To: <%s>%s%s%s%s\r\n"
705 "Max-Forwards: 70\r\n"
710 "Content-Length: %" G_GSIZE_FORMAT
"\r\n\r\n%s",
712 dialog
&& dialog
->request
? dialog
->request
: url
,
713 TRANSPORT_DESCRIPTOR
,
714 transport
->uri_address
,
715 transport
->connection
->client_port
,
716 branch
? ";branch=" : "",
717 branch
? branch
: "",
718 sipe_private
->username
,
719 ourtag
? ";tag=" : "",
720 ourtag
? ourtag
: "",
723 theirtag
? ";tag=" : "",
724 theirtag
? theirtag
: "",
725 theirepid
? ";epid=" : "",
726 theirepid
? theirepid
: "",
729 sipe_core_user_agent(sipe_private
),
732 addheaders
? addheaders
: "",
733 body
? (gsize
) strlen(body
) : 0,
737 //printf ("parsing msg buf:\n%s\n\n", buf);
738 msg
= sipmsg_parse_msg(buf
);
747 sign_outgoing_message(sipe_private
, msg
);
749 /* The authentication scheme is not ready so we can't send the message.
750 This should only happen for REGISTER messages. */
751 if (!transport
->auth_incomplete
) {
752 buf
= sipmsg_to_string(msg
);
754 /* add to ongoing transactions */
755 /* ACK isn't supposed to be answered ever. So we do not keep transaction for it. */
756 if (!sipe_strequal(method
, "ACK")) {
757 trans
= g_new0(struct transaction
, 1);
758 trans
->callback
= callback
;
760 trans
->key
= g_strdup_printf("<%s><%d %s>", callid
, cseq
, method
);
761 if (timeout_callback
) {
762 trans
->timeout_callback
= timeout_callback
;
763 trans
->timeout_key
= g_strdup_printf("<transaction timeout>%s", trans
->key
);
764 sipe_schedule_seconds(sipe_private
,
768 transaction_timeout_cb
,
771 transport
->transactions
= g_slist_append(transport
->transactions
,
773 SIPE_DEBUG_INFO("SIP transactions count:%d after addition", g_slist_length(transport
->transactions
));
776 send_sip_message(transport
, buf
);
780 if (!trans
) sipmsg_free(msg
);
785 struct transaction
*sip_transport_request(struct sipe_core_private
*sipe_private
,
789 const gchar
*addheaders
,
791 struct sip_dialog
*dialog
,
792 TransCallback callback
)
794 return sip_transport_request_timeout(sipe_private
,
806 static void sip_transport_simple_request(struct sipe_core_private
*sipe_private
,
808 struct sip_dialog
*dialog
)
810 sip_transport_request(sipe_private
,
820 void sip_transport_ack(struct sipe_core_private
*sipe_private
,
821 struct sip_dialog
*dialog
)
823 sip_transport_simple_request(sipe_private
, "ACK", dialog
);
826 void sip_transport_bye(struct sipe_core_private
*sipe_private
,
827 struct sip_dialog
*dialog
)
829 sip_transport_simple_request(sipe_private
, "BYE", dialog
);
832 struct transaction
*sip_transport_info(struct sipe_core_private
*sipe_private
,
833 const gchar
*addheaders
,
835 struct sip_dialog
*dialog
,
836 TransCallback callback
)
838 return sip_transport_request(sipe_private
,
848 struct transaction
*sip_transport_invite(struct sipe_core_private
*sipe_private
,
849 const gchar
*addheaders
,
851 struct sip_dialog
*dialog
,
852 TransCallback callback
)
854 return sip_transport_request(sipe_private
,
864 struct transaction
*sip_transport_service(struct sipe_core_private
*sipe_private
,
866 const gchar
*addheaders
,
868 TransCallback callback
)
870 return sip_transport_request(sipe_private
,
880 void sip_transport_subscribe(struct sipe_core_private
*sipe_private
,
882 const gchar
*addheaders
,
884 struct sip_dialog
*dialog
,
885 TransCallback callback
)
887 sip_transport_request(sipe_private
,
897 void sip_transport_update(struct sipe_core_private
*sipe_private
,
898 struct sip_dialog
*dialog
,
899 TransCallback callback
)
901 sip_transport_request(sipe_private
,
911 static const gchar
*get_auth_header(struct sipe_core_private
*sipe_private
,
915 struct sip_auth
*auth
= &sipe_private
->transport
->registrar
;
918 auth
->protocol
= auth_type_to_protocol
[auth
->type
];
920 return(sipmsg_find_auth_header(msg
, auth
->protocol
));
923 static void do_register(struct sipe_core_private
*sipe_private
,
924 gboolean deregister
);
926 static void do_reauthenticate_cb(struct sipe_core_private
*sipe_private
,
927 SIPE_UNUSED_PARAMETER gpointer unused
)
929 struct sip_transport
*transport
= sipe_private
->transport
;
931 /* register again when security token expires */
932 /* we have to start a new authentication as the security token
933 * is almost expired by sending a not signed REGISTER message */
934 SIPE_LOG_INFO_NOFORMAT("do_reauthenticate_cb: do a full reauthentication");
935 sipe_auth_free(&transport
->registrar
);
936 sipe_auth_free(&transport
->proxy
);
937 sipe_schedule_cancel(sipe_private
, "<registration>");
938 transport
->auth_retry
= TRUE
;
939 transport
->reregister_set
= FALSE
;
940 transport
->register_attempt
= 0;
941 do_register(sipe_private
, FALSE
);
942 transport
->reauthenticate_set
= FALSE
;
945 static void sip_transport_default_contact(struct sipe_core_private
*sipe_private
)
947 struct sip_transport
*transport
= sipe_private
->transport
;
948 sipe_private
->contact
= g_strdup_printf("<sip:%s:%d;maddr=%s;transport=%s>;proxy=replace",
949 sipe_private
->username
,
950 transport
->connection
->client_port
,
951 transport
->uri_address
,
952 TRANSPORT_DESCRIPTOR
);
955 static void do_register_cb(struct sipe_core_private
*sipe_private
,
956 SIPE_UNUSED_PARAMETER
void *unused
)
958 do_register(sipe_private
, FALSE
);
961 static void sip_transport_set_reregister(struct sipe_core_private
*sipe_private
,
964 sipe_schedule_seconds(sipe_private
,
972 static void sipe_server_register(struct sipe_core_private
*sipe_private
,
977 static gboolean
process_register_response(struct sipe_core_private
*sipe_private
,
979 SIPE_UNUSED_PARAMETER
struct transaction
*trans
)
981 struct sip_transport
*transport
= sipe_private
->transport
;
982 const gchar
*expires_header
;
984 GSList
*hdr
= msg
->headers
;
985 struct sipnameval
*elem
;
987 expires_header
= sipmsg_find_header(msg
, "Expires");
988 expires
= expires_header
!= NULL
? strtol(expires_header
, NULL
, 10) : 0;
989 SIPE_DEBUG_INFO("process_register_response: got response to REGISTER; expires = %d", expires
);
991 switch (msg
->response
) {
994 const gchar
*contact_hdr
;
995 const gchar
*auth_hdr
;
1000 if (!transport
->reregister_set
) {
1001 /* Schedule re-register 30 seconds before expiration */
1004 sip_transport_set_reregister(sipe_private
,
1006 transport
->reregister_set
= TRUE
;
1009 auth_hdr
= sipmsg_find_auth_header(msg
,
1010 transport
->registrar
.protocol
);
1012 SIPE_DEBUG_INFO("process_register_response: Auth header: %s", auth_hdr
);
1013 fill_auth(auth_hdr
, &transport
->registrar
);
1016 if (!transport
->reauthenticate_set
) {
1017 /* [MS-SIPAE] Section 3.2.2 Timers
1019 * When the ... authentication handshake completes
1020 * and the SA enters the "established" state, the
1021 * SIP protocol client MUST start an SA expiration
1024 * The expiration timer value is the lesser of
1026 * - Kerberos: the service ticket expiry time
1027 * - TLS-DSK: the certificate expiration time
1029 * and eight hours, further reduced by some buffer
1032 * The protocol client MUST choose a sufficient
1033 * buffer time to allow for the ... authentication
1034 * handshake that reestablishes the SA to complete
1035 * ... This value SHOULD be five (5) minutes or
1038 guint reauth_timeout
= transport
->registrar
.expires
;
1040 SIPE_LOG_INFO_NOFORMAT("process_register_response: authentication handshake completed successfully");
1042 if ((reauth_timeout
== 0) ||
1043 (reauth_timeout
> 8 * 60 * 60))
1044 reauth_timeout
= 8 * 60 * 60;
1045 if (reauth_timeout
> 5 * 60)
1046 reauth_timeout
-= 5 * 60;
1048 sipe_schedule_seconds(sipe_private
,
1049 "<+reauthentication>",
1052 do_reauthenticate_cb
,
1054 transport
->reauthenticate_set
= TRUE
;
1057 uuid
= get_uuid(sipe_private
);
1059 // There can be multiple Contact headers (one per location where the user is logged in) so
1060 // make sure to only get the one for this uuid
1061 for (i
= 0; (contact_hdr
= sipmsg_find_header_instance (msg
, "Contact", i
)); i
++) {
1062 gchar
* valid_contact
= sipmsg_find_part_of_header (contact_hdr
, uuid
, NULL
, NULL
);
1063 if (valid_contact
) {
1064 gruu
= sipmsg_find_part_of_header(contact_hdr
, "gruu=\"", "\"", NULL
);
1065 //SIPE_DEBUG_INFO("process_register_response: got gruu %s from contact hdr w/ right uuid: %s", gruu, contact_hdr);
1066 g_free(valid_contact
);
1069 //SIPE_DEBUG_INFO("process_register_response: ignoring contact hdr b/c not right uuid: %s", contact_hdr);
1074 g_free(sipe_private
->contact
);
1076 sipe_private
->contact
= g_strdup_printf("<%s>", gruu
);
1079 //SIPE_DEBUG_INFO_NOFORMAT("process_register_response: didn't find gruu in a Contact hdr");
1080 sip_transport_default_contact(sipe_private
);
1082 SIPE_CORE_PRIVATE_FLAG_UNSET(OCS2007
);
1083 SIPE_CORE_PRIVATE_FLAG_UNSET(REMOTE_USER
);
1084 SIPE_CORE_PRIVATE_FLAG_UNSET(BATCHED_SUPPORT
);
1085 SIPE_CORE_PRIVATE_FLAG_UNSET(SFB
);
1090 if (sipe_strcase_equal(elem
->name
, "Supported")) {
1091 if (sipe_strcase_equal(elem
->value
, "msrtc-event-categories")) {
1092 /* We interpret this as OCS2007+ indicator */
1093 SIPE_CORE_PRIVATE_FLAG_SET(OCS2007
);
1094 SIPE_LOG_INFO("process_register_response: Supported: %s (indicates OCS2007+)", elem
->value
);
1096 if (sipe_strcase_equal(elem
->value
, "adhoclist")) {
1097 SIPE_CORE_PRIVATE_FLAG_SET(BATCHED_SUPPORT
);
1098 SIPE_DEBUG_INFO("process_register_response: Supported: %s", elem
->value
);
1100 } else if (sipe_strcase_equal(elem
->name
, "Allow-Events")){
1101 gchar
**caps
= g_strsplit(elem
->value
,",",0);
1104 sipe_private
->allowed_events
= g_slist_append(sipe_private
->allowed_events
, g_strdup(caps
[i
]));
1105 SIPE_DEBUG_INFO("process_register_response: Allow-Events: %s", caps
[i
]);
1109 } else if (sipe_strcase_equal(elem
->name
, "ms-user-logon-data")) {
1110 if (sipe_strcase_equal(elem
->value
, "RemoteUser")) {
1111 SIPE_CORE_PRIVATE_FLAG_SET(REMOTE_USER
);
1112 SIPE_DEBUG_INFO_NOFORMAT("process_register_response: ms-user-logon-data: RemoteUser (connected "
1113 "via Edge Server)");
1115 } else if (sipe_strcase_equal(elem
->name
, "Server")) {
1116 /* Server string has format like 'RTC/6.0'.
1117 * We want to check the first digit. */
1118 gchar
**parts
= g_strsplit_set(elem
->value
, "/.", 3);
1119 if (g_strv_length(parts
) > 1) {
1120 guint version
= atoi(parts
[1]);
1122 SIPE_CORE_PRIVATE_FLAG_SET(SFB
);
1123 SIPE_LOG_INFO("process_register_response: server version is %d >= 6 (indicates Skype for Business+)", version
);
1128 hdr
= g_slist_next(hdr
);
1131 sipe_backend_connection_completed(SIPE_CORE_PUBLIC
);
1133 /* rejoin open chats to be able to use them by continue to send messages */
1134 sipe_backend_chat_rejoin_all(SIPE_CORE_PUBLIC
);
1136 /* subscriptions, done only once */
1137 if (!transport
->subscribed
) {
1138 sipe_subscription_self_events(sipe_private
);
1139 transport
->subscribed
= TRUE
;
1142 timeout
= sipmsg_find_part_of_header(sipmsg_find_header(msg
, "ms-keep-alive"),
1143 "timeout=", ";", NULL
);
1144 if (timeout
!= NULL
) {
1145 sscanf(timeout
, "%u", &transport
->keepalive_timeout
);
1146 SIPE_DEBUG_INFO("process_register_response: server determined keep alive timeout is %u seconds",
1147 transport
->keepalive_timeout
);
1151 SIPE_DEBUG_INFO("process_register_response: got 200, removing CSeq: %d", transport
->cseq
);
1156 gchar
*redirect
= parse_from(sipmsg_find_header(msg
, "Contact"));
1158 SIPE_LOG_INFO_NOFORMAT("process_register_response: authentication handshake completed successfully (with redirect)");
1160 if (redirect
&& (g_ascii_strncasecmp("sip:", redirect
, 4) == 0)) {
1161 gchar
**parts
= g_strsplit(redirect
+ 4, ";", 0);
1165 guint transport_type
= SIPE_TRANSPORT_TLS
;
1168 tmp
= g_strsplit(parts
[0], ":", 0);
1169 hostname
= g_strdup(tmp
[0]);
1170 if (tmp
[1]) port
= strtoul(tmp
[1], NULL
, 10);
1174 tmp
= g_strsplit(parts
[i
], "=", 0);
1176 if (g_ascii_strcasecmp("transport", tmp
[0]) == 0) {
1177 if (g_ascii_strcasecmp("tcp", tmp
[1]) == 0) {
1178 transport_type
= SIPE_TRANSPORT_TCP
;
1187 /* Close old connection */
1188 sipe_core_connection_cleanup(sipe_private
);
1189 /* transport and sipe_private->transport are invalid after this */
1191 /* Create new connection */
1192 sipe_server_register(sipe_private
, transport_type
, hostname
, port
);
1193 /* sipe_private->transport has a new value */
1194 SIPE_DEBUG_INFO("process_register_response: redirected to host %s port %d transport %d",
1195 hostname
, port
, transport_type
);
1202 const char *auth_hdr
= NULL
;
1204 SIPE_DEBUG_INFO("process_register_response: REGISTER retries %d", transport
->registrar
.retries
);
1206 if (transport
->reauthenticate_set
) {
1207 SIPE_DEBUG_ERROR_NOFORMAT("process_register_response: RE-REGISTER rejected, triggering re-authentication");
1208 do_reauthenticate_cb(sipe_private
, NULL
);
1212 if (sip_sec_context_is_ready(transport
->registrar
.gssapi_context
)) {
1213 struct sip_auth
*auth
= &transport
->registrar
;
1215 /* NTLM is the scheme with lowest priority - don't retry */
1216 if (auth_can_retry(transport
, auth
)) {
1217 guint failed
= auth
->type
;
1218 SIPE_DEBUG_INFO_NOFORMAT("process_register_response: authentication handshake failed - trying next authentication scheme.");
1219 sipe_auth_free(auth
);
1220 auth
->type
= failed
;
1222 SIPE_LOG_ERROR_NOFORMAT("process_register_response: authentication handshake failed - giving up.");
1223 sipe_backend_connection_error(SIPE_CORE_PUBLIC
,
1224 SIPE_CONNECTION_ERROR_AUTHENTICATION_FAILED
,
1225 _("Authentication failed"));
1230 if (sipe_private
->authentication_type
== SIPE_AUTHENTICATION_TYPE_AUTOMATIC
) {
1231 struct sip_auth
*auth
= &transport
->registrar
;
1232 guint
try = auth
->type
;
1236 * Determine next authentication
1237 * scheme in priority order
1239 if (transport
->auth_retry
)
1241 case SIPE_AUTHENTICATION_TYPE_UNSET
:
1242 try = SIPE_AUTHENTICATION_TYPE_TLS_DSK
;
1245 case SIPE_AUTHENTICATION_TYPE_TLS_DSK
:
1246 #if defined(HAVE_GSSAPI_GSSAPI_H) || defined(HAVE_SSPI)
1247 try = SIPE_AUTHENTICATION_TYPE_KERBEROS
;
1250 case SIPE_AUTHENTICATION_TYPE_KERBEROS
:
1252 try = SIPE_AUTHENTICATION_TYPE_NTLM
;
1256 try = SIPE_AUTHENTICATION_TYPE_UNSET
;
1260 auth
->can_retry
= (try != SIPE_AUTHENTICATION_TYPE_UNSET
);
1262 if (!auth
->can_retry
) {
1263 SIPE_DEBUG_INFO_NOFORMAT("process_register_response: no more authentication schemes to try");
1267 auth_hdr
= get_auth_header(sipe_private
,
1272 transport
->auth_retry
= FALSE
;
1275 auth_hdr
= get_auth_header(sipe_private
,
1276 sipe_private
->authentication_type
,
1280 sipe_backend_connection_error(SIPE_CORE_PUBLIC
,
1281 SIPE_CONNECTION_ERROR_AUTHENTICATION_IMPOSSIBLE
,
1282 _("Incompatible authentication scheme chosen"));
1285 SIPE_DEBUG_INFO("process_register_response: Auth header: %s", auth_hdr
);
1286 fill_auth(auth_hdr
, &transport
->registrar
);
1287 transport
->reregister_set
= FALSE
;
1288 transport
->register_attempt
= 0;
1289 do_register(sipe_private
,
1290 sipe_backend_connection_is_disconnecting(SIPE_CORE_PUBLIC
));
1297 sipmsg_parse_warning(msg
, &reason
);
1298 reason
= reason
? reason
: sipmsg_get_ms_diagnostics_public_reason(msg
);
1299 warning
= g_strdup_printf(_("You have been rejected by the server: %s"),
1300 reason
? reason
: _("no reason given"));
1303 sipe_backend_connection_error(SIPE_CORE_PUBLIC
,
1304 SIPE_CONNECTION_ERROR_INVALID_SETTINGS
,
1312 const gchar
*diagnostics
= sipmsg_find_header(msg
, "ms-diagnostics");
1313 gchar
*reason
= sipmsg_get_ms_diagnostics_reason(msg
);
1315 warning
= g_strdup_printf(_("Not found: %s. Please contact your Administrator"),
1316 diagnostics
? (reason
? reason
: _("no reason given")) :
1317 _("SIP is either not enabled for the destination URI or it does not exist"));
1320 sipe_backend_connection_error(SIPE_CORE_PUBLIC
,
1321 SIPE_CONNECTION_ERROR_INVALID_USERNAME
,
1327 case 504: /* Server time-out */
1328 /* first attempt + 5 retries */
1329 if (transport
->register_attempt
< 6) {
1330 SIPE_DEBUG_INFO("process_register_response: RE-REGISTER timeout on attempt %d, retrying later",
1331 transport
->register_attempt
);
1332 sip_transport_set_reregister(sipe_private
, 60);
1338 gchar
*reason
= sipmsg_get_ms_diagnostics_reason(msg
);
1340 warning
= g_strdup_printf(_("Service unavailable: %s"), reason
? reason
: _("no reason given"));
1343 sipe_backend_connection_error(SIPE_CORE_PUBLIC
,
1344 SIPE_CONNECTION_ERROR_NETWORK
,
1354 static gboolean
register_response_timeout(struct sipe_core_private
*sipe_private
,
1355 SIPE_UNUSED_PARAMETER
struct sipmsg
*msg
,
1356 SIPE_UNUSED_PARAMETER
struct transaction
*trans
)
1358 struct sip_transport
*transport
= sipe_private
->transport
;
1359 if (transport
->register_attempt
< 6) {
1360 SIPE_DEBUG_INFO("register_response_timeout: no answer to attempt %d, retrying",
1361 transport
->register_attempt
);
1362 do_register(sipe_private
, FALSE
);
1364 gchar
*warning
= g_strdup_printf(_("Service unavailable: %s"), _("no reason given"));
1365 sipe_backend_connection_error(SIPE_CORE_PUBLIC
,
1366 SIPE_CONNECTION_ERROR_NETWORK
,
1373 static void do_register(struct sipe_core_private
*sipe_private
,
1374 gboolean deregister
)
1376 struct sip_transport
*transport
= sipe_private
->transport
;
1382 if (!sipe_private
->public.sip_domain
) return;
1385 if (transport
->reregister_set
) {
1386 transport
->reregister_set
= FALSE
;
1387 transport
->register_attempt
= 1;
1389 transport
->register_attempt
++;
1393 transport
->deregister
= deregister
;
1394 transport
->auth_incomplete
= FALSE
;
1396 uuid
= get_uuid(sipe_private
);
1397 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"
1398 "Supported: gruu-10, adhoclist, msrtc-event-categories, com.microsoft.msrtc.presence\r\n"
1399 "Event: registration\r\n"
1400 "Allow-Events: presence\r\n"
1401 "ms-keep-alive: UAC;hop-hop=yes\r\n"
1403 transport
->uri_address
,
1404 transport
->connection
->client_port
,
1405 TRANSPORT_DESCRIPTOR
,
1407 deregister
? "Expires: 0\r\n" : "");
1410 uri
= sip_uri_from_name(sipe_private
->public.sip_domain
);
1411 to
= sip_uri_self(sipe_private
);
1412 sip_transport_request_timeout(sipe_private
,
1419 process_register_response
,
1421 deregister
? NULL
: register_response_timeout
);
1427 /* Make sure that all messages are pushed to the server
1428 before the connection gets shut down */
1429 SIPE_LOG_INFO_NOFORMAT("De-register from server. Flushing outstanding messages.");
1430 sipe_backend_transport_flush(transport
->connection
);
1434 void sip_transport_deregister(struct sipe_core_private
*sipe_private
)
1436 do_register(sipe_private
, TRUE
);
1439 void sip_transport_disconnect(struct sipe_core_private
*sipe_private
)
1441 struct sip_transport
*transport
= sipe_private
->transport
;
1443 /* transport can be NULL during connection setup */
1445 SIPE_LOG_INFO("sip_transport_disconnect: dropping connection '%s:%u'(%p)",
1446 transport
->server_name
,
1447 transport
->server_port
,
1448 transport
->connection
);
1450 sipe_backend_transport_disconnect(transport
->connection
);
1452 sipe_auth_free(&transport
->registrar
);
1453 sipe_auth_free(&transport
->proxy
);
1455 g_free(transport
->server_name
);
1456 g_free(transport
->uri_address
);
1457 g_free(transport
->ip_address
);
1458 g_free(transport
->epid
);
1460 while (transport
->transactions
)
1461 transactions_remove(sipe_private
,
1462 transport
->transactions
->data
);
1467 sipe_private
->transport
= NULL
;
1468 sipe_private
->service_data
= NULL
;
1469 sipe_private
->address_data
= NULL
;
1471 sipe_schedule_cancel(sipe_private
, "<+keepalive-timeout>");
1473 if (sipe_private
->dns_query
)
1474 sipe_backend_dns_query_cancel(sipe_private
->dns_query
);
1478 void sip_transport_authentication_completed(struct sipe_core_private
*sipe_private
)
1480 do_reauthenticate_cb(sipe_private
, NULL
);
1483 guint
sip_transport_port(struct sipe_core_private
*sipe_private
)
1485 return sipe_private
->transport
->server_port
;
1488 static void process_input_message(struct sipe_core_private
*sipe_private
,
1491 struct sip_transport
*transport
= sipe_private
->transport
;
1492 gboolean notfound
= FALSE
;
1493 const char *method
= msg
->method
? msg
->method
: "NOT FOUND";
1495 SIPE_DEBUG_INFO("process_input_message: msg->response(%d),msg->method(%s)",
1496 msg
->response
, method
);
1498 if (msg
->response
== 0) { /* request */
1499 if (sipe_strequal(method
, "MESSAGE")) {
1500 process_incoming_message(sipe_private
, msg
);
1501 } else if (sipe_strequal(method
, "NOTIFY")) {
1502 SIPE_DEBUG_INFO_NOFORMAT("send->process_incoming_notify");
1503 process_incoming_notify(sipe_private
, msg
);
1504 sip_transport_response(sipe_private
, msg
, 200, "OK", NULL
);
1505 } else if (sipe_strequal(method
, "BENOTIFY")) {
1506 SIPE_DEBUG_INFO_NOFORMAT("send->process_incoming_benotify");
1507 process_incoming_notify(sipe_private
, msg
);
1508 } else if (sipe_strequal(method
, "INVITE")) {
1509 process_incoming_invite(sipe_private
, msg
);
1510 } else if (sipe_strequal(method
, "REFER")) {
1511 process_incoming_refer(sipe_private
, msg
);
1512 } else if (sipe_strequal(method
, "OPTIONS")) {
1513 process_incoming_options(sipe_private
, msg
);
1514 } else if (sipe_strequal(method
, "INFO")) {
1515 process_incoming_info(sipe_private
, msg
);
1516 } else if (sipe_strequal(method
, "ACK")) {
1517 /* ACK's don't need any response */
1518 } else if (sipe_strequal(method
, "PRACK")) {
1519 sip_transport_response(sipe_private
, msg
, 200, "OK", NULL
);
1520 } else if (sipe_strequal(method
, "SUBSCRIBE")) {
1521 /* LCS 2005 sends us these - just respond 200 OK */
1522 sip_transport_response(sipe_private
, msg
, 200, "OK", NULL
);
1523 } else if (sipe_strequal(method
, "CANCEL")) {
1524 process_incoming_cancel(sipe_private
, msg
);
1525 } else if (sipe_strequal(method
, "BYE")) {
1526 process_incoming_bye(sipe_private
, msg
);
1528 sip_transport_response(sipe_private
, msg
, 501, "Not implemented", NULL
);
1532 } else { /* response */
1533 struct transaction
*trans
= transactions_find(transport
, msg
);
1535 if (msg
->response
< 200) {
1536 /* ignore provisional response */
1537 SIPE_DEBUG_INFO("process_input_message: got provisional (%d) response, ignoring", msg
->response
);
1539 /* Transaction not yet completed */
1542 } else if (msg
->response
== 401) { /* Unauthorized */
1544 if (sipe_strequal(trans
->msg
->method
, "REGISTER")) {
1545 /* Expected response during authentication handshake */
1546 transport
->registrar
.retries
++;
1547 SIPE_DEBUG_INFO("process_input_message: RE-REGISTER CSeq: %d", transport
->cseq
);
1551 /* Are we registered? */
1552 if (transport
->reregister_set
) {
1553 SIPE_DEBUG_INFO_NOFORMAT("process_input_message: 401 response to non-REGISTER message. Retrying with new authentication.");
1554 sipmsg_remove_header_now(trans
->msg
, "Authorization");
1555 sign_outgoing_message(sipe_private
,
1559 * We don't have a valid authentication at the moment.
1560 * Resend message unchanged. It will be rejected again
1561 * and hopefully by then we have a valid authentication.
1563 SIPE_DEBUG_INFO_NOFORMAT("process_input_message: 401 response to non-REGISTER message. Bouncing...");
1566 /* Resend request */
1567 resend
= sipmsg_to_string(trans
->msg
);
1568 send_sip_message(sipe_private
->transport
, resend
);
1571 /* Transaction not yet completed */
1575 } else if (msg
->response
== 407) { /* Proxy Authentication Required */
1577 if (transport
->proxy
.retries
++ <= 30) {
1578 const gchar
*proxy_hdr
= sipmsg_find_header(msg
, "Proxy-Authenticate");
1583 if (!g_ascii_strncasecmp(proxy_hdr
, "Digest", 6)) {
1584 auth
= sip_sec_digest_authorization(sipe_private
,
1591 transport
->proxy
.type
= SIPE_AUTHENTICATION_TYPE_UNSET
;
1592 for (i
= 0; i
< AUTH_PROTOCOLS
; i
++) {
1593 const gchar
*protocol
= auth_type_to_protocol
[i
];
1595 !g_ascii_strncasecmp(proxy_hdr
, protocol
, strlen(protocol
))) {
1596 SIPE_DEBUG_INFO("process_input_message: proxy authentication scheme '%s'", protocol
);
1597 transport
->proxy
.type
= i
;
1598 transport
->proxy
.protocol
= protocol
;
1599 fill_auth(proxy_hdr
, &transport
->proxy
);
1600 auth
= auth_header(sipe_private
, &transport
->proxy
, trans
->msg
);
1609 /* replace old proxy authentication with new one */
1610 sipmsg_remove_header_now(trans
->msg
, "Proxy-Authorization");
1611 sipmsg_add_header_now(trans
->msg
, "Proxy-Authorization", auth
);
1614 /* resend request with proxy authentication */
1615 resend
= sipmsg_to_string(trans
->msg
);
1616 send_sip_message(sipe_private
->transport
, resend
);
1619 /* Transaction not yet completed */
1623 SIPE_DEBUG_ERROR_NOFORMAT("process_input_message: can't generate proxy authentication. Giving up.");
1625 SIPE_DEBUG_ERROR_NOFORMAT("process_input_message: 407 response without 'Proxy-Authenticate' header. Giving up.");
1627 SIPE_DEBUG_ERROR_NOFORMAT("process_input_message: too many proxy authentication retries. Giving up.");
1630 transport
->registrar
.retries
= 0;
1631 transport
->proxy
.retries
= 0;
1634 /* Is transaction completed? */
1636 if (trans
->callback
) {
1637 SIPE_DEBUG_INFO_NOFORMAT("process_input_message: we have a transaction callback");
1638 /* call the callback to process response */
1639 (trans
->callback
)(sipe_private
, msg
, trans
);
1640 /* transport && trans no longer valid after redirect */
1644 * Redirect case: sipe_private->transport is
1645 * the new transport with empty queue
1647 if (sipe_private
->transport
->transactions
) {
1648 SIPE_DEBUG_INFO("process_input_message: removing CSeq %d", transport
->cseq
);
1649 transactions_remove(sipe_private
, trans
);
1653 SIPE_DEBUG_INFO_NOFORMAT("process_input_message: received response to unknown transaction");
1659 SIPE_DEBUG_INFO("received a unknown sip message with method %s and response %d", method
, msg
->response
);
1663 static void sip_transport_input(struct sipe_transport_connection
*conn
)
1665 struct sipe_core_private
*sipe_private
= conn
->user_data
;
1666 struct sip_transport
*transport
= sipe_private
->transport
;
1667 gchar
*cur
= conn
->buffer
;
1669 /* according to the RFC remove CRLF at the beginning */
1670 while (*cur
== '\r' || *cur
== '\n') {
1673 if (cur
!= conn
->buffer
)
1674 sipe_utils_shrink_buffer(conn
, cur
);
1676 /* Received a full Header? */
1677 transport
->processing_input
= TRUE
;
1678 while (transport
->processing_input
&&
1679 ((cur
= strstr(conn
->buffer
, "\r\n\r\n")) != NULL
)) {
1685 msg
= sipmsg_parse_header(conn
->buffer
);
1688 remainder
= conn
->buffer_used
- (cur
- conn
->buffer
);
1689 if (msg
&& remainder
>= (guint
) msg
->bodylen
) {
1690 char *dummy
= g_malloc(msg
->bodylen
+ 1);
1691 memcpy(dummy
, cur
, msg
->bodylen
);
1692 dummy
[msg
->bodylen
] = '\0';
1694 cur
+= msg
->bodylen
;
1695 sipe_utils_message_debug(conn
,
1700 sipe_utils_shrink_buffer(conn
, cur
);
1703 SIPE_DEBUG_INFO("sipe_transport_input: body too short (%d < %d, strlen %d) - ignoring message", remainder
, msg
->bodylen
, (int)strlen(conn
->buffer
));
1707 /* restore header for next try */
1712 /* Fatal header parse error? */
1713 if (msg
->response
== SIPMSG_RESPONSE_FATAL_ERROR
) {
1714 /* can't proceed -> drop connection */
1715 sipe_backend_connection_error(SIPE_CORE_PUBLIC
,
1716 SIPE_CONNECTION_ERROR_NETWORK
,
1717 _("Corrupted message received"));
1718 transport
->processing_input
= FALSE
;
1720 /* Verify the signature before processing it */
1721 } else if (sip_sec_context_is_ready(transport
->registrar
.gssapi_context
)) {
1722 struct sipmsg_breakdown msgbd
;
1723 gchar
*signature_input_str
;
1726 sipmsg_breakdown_parse(&msgbd
, transport
->registrar
.realm
, transport
->registrar
.target
,
1727 transport
->registrar
.protocol
);
1728 signature_input_str
= sipmsg_breakdown_get_string(transport
->registrar
.version
, &msgbd
);
1730 rspauth
= sipmsg_find_part_of_header(sipmsg_find_header(msg
, "Authentication-Info"), "rspauth=\"", "\"", NULL
);
1732 if (rspauth
!= NULL
) {
1733 if (sip_sec_verify_signature(transport
->registrar
.gssapi_context
, signature_input_str
, rspauth
)) {
1734 SIPE_DEBUG_INFO_NOFORMAT("sip_transport_input: signature of incoming message validated");
1735 process_input_message(sipe_private
, msg
);
1736 /* transport is invalid after redirect */
1738 SIPE_DEBUG_INFO_NOFORMAT("sip_transport_input: signature of incoming message is invalid.");
1739 sipe_backend_connection_error(SIPE_CORE_PUBLIC
,
1740 SIPE_CONNECTION_ERROR_NETWORK
,
1741 _("Invalid message signature received"));
1742 transport
->processing_input
= FALSE
;
1744 } else if ((msg
->response
== 401) ||
1745 sipe_strequal(msg
->method
, "REGISTER")) {
1746 /* a) Retry non-REGISTER requests with updated authentication */
1747 /* b) We must always process REGISTER responses */
1748 process_input_message(sipe_private
, msg
);
1750 /* OCS sends provisional messages that are *not* signed */
1751 if (msg
->response
>= 200) {
1752 /* We are not calling process_input_message(),
1753 so we need to drop the transaction here. */
1754 struct transaction
*trans
= transactions_find(transport
, msg
);
1755 if (trans
) transactions_remove(sipe_private
, trans
);
1757 SIPE_DEBUG_INFO_NOFORMAT("sip_transport_input: message without authentication data - ignoring");
1759 g_free(signature_input_str
);
1762 sipmsg_breakdown_free(&msgbd
);
1764 process_input_message(sipe_private
, msg
);
1769 /* Redirect: old content of "transport" & "conn" is no longer valid */
1770 transport
= sipe_private
->transport
;
1771 conn
= transport
->connection
;
1775 static void sip_transport_connected(struct sipe_transport_connection
*conn
)
1777 struct sipe_core_private
*sipe_private
= conn
->user_data
;
1778 struct sip_transport
*transport
= sipe_private
->transport
;
1779 gchar
*self_sip_uri
= sip_uri_self(sipe_private
);
1781 SIPE_LOG_INFO("sip_transport_connected: %s:%u(%p)",
1782 transport
->server_name
, transport
->server_port
, conn
);
1784 while (sipe_private
->lync_autodiscover_servers
)
1785 sipe_private
->lync_autodiscover_servers
=
1786 sipe_lync_autodiscover_pop(sipe_private
->lync_autodiscover_servers
);
1788 sipe_private
->service_data
= NULL
;
1789 sipe_private
->address_data
= NULL
;
1792 * Initial keepalive timeout during REGISTER phase
1794 * NOTE: 60 seconds is a guess. Needs more testing!
1796 transport
->keepalive_timeout
= 60;
1797 start_keepalive_timer(sipe_private
, transport
->keepalive_timeout
);
1799 transport
->ip_address
= sipe_backend_transport_ip_address(conn
);
1800 if (strchr(transport
->ip_address
, ':') != NULL
)
1801 /* RFC2732: Format for Literal IPv6 Addresses in URL's */
1802 transport
->uri_address
= g_strdup_printf("[%s]", transport
->ip_address
);
1804 transport
->uri_address
= g_strdup(transport
->ip_address
);
1805 transport
->sdp_marker
= sipe_utils_ip_sdp_address_marker(transport
->ip_address
);
1806 transport
->epid
= sipe_get_epid(self_sip_uri
,
1808 transport
->ip_address
);
1809 g_free(self_sip_uri
);
1811 do_register(sipe_private
, FALSE
);
1814 static void resolve_next_lync(struct sipe_core_private
*sipe_private
);
1815 static void resolve_next_service(struct sipe_core_private
*sipe_private
,
1816 const struct sip_service_data
*start
);
1817 static void resolve_next_address(struct sipe_core_private
*sipe_private
,
1819 static void sip_transport_error(struct sipe_transport_connection
*conn
,
1822 struct sipe_core_private
*sipe_private
= conn
->user_data
;
1824 /* This failed attempt was based on a Lync Autodiscover result */
1825 if (sipe_private
->lync_autodiscover_servers
) {
1826 resolve_next_lync(sipe_private
);
1827 /* This failed attempt was based on a DNS SRV record */
1828 } else if (sipe_private
->service_data
) {
1829 resolve_next_service(sipe_private
, NULL
);
1830 /* This failed attempt was based on a DNS A record */
1831 } else if (sipe_private
->address_data
) {
1832 resolve_next_address(sipe_private
, FALSE
);
1834 sipe_backend_connection_error(SIPE_CORE_PUBLIC
,
1835 SIPE_CONNECTION_ERROR_NETWORK
,
1840 /* server_name must be g_alloc()'ed */
1841 static void sipe_server_register(struct sipe_core_private
*sipe_private
,
1846 sipe_connect_setup setup
= {
1849 (server_port
!= 0) ? server_port
:
1850 (type
== SIPE_TRANSPORT_TLS
) ? 5061 : 5060,
1852 sip_transport_connected
,
1853 sip_transport_input
,
1856 struct sip_transport
*transport
= g_new0(struct sip_transport
, 1);
1858 transport
->auth_retry
= TRUE
;
1859 transport
->server_name
= server_name
;
1860 transport
->server_port
= setup
.server_port
;
1861 transport
->connection
= sipe_backend_transport_connect(SIPE_CORE_PUBLIC
,
1863 sipe_private
->transport
= transport
;
1866 struct sip_service_data
{
1867 const char *protocol
;
1868 const char *transport
;
1873 * Autodiscover using DNS SRV records. See RFC2782/3263
1875 * Service list for AUTO
1877 static const struct sip_service_data service_autodetect
[] = {
1878 { "sipinternaltls", "tcp", SIPE_TRANSPORT_TLS
}, /* for internal TLS connections */
1879 { "sipinternal", "tcp", SIPE_TRANSPORT_TCP
}, /* for internal TCP connections */
1880 { "sip", "tls", SIPE_TRANSPORT_TLS
}, /* for external TLS connections */
1881 { "sip", "tcp", SIPE_TRANSPORT_TCP
}, /*.for external TCP connections */
1885 /* Service list for SSL/TLS */
1886 static const struct sip_service_data service_tls
[] = {
1887 { "sipinternaltls", "tcp", SIPE_TRANSPORT_TLS
}, /* for internal TLS connections */
1888 { "sip", "tls", SIPE_TRANSPORT_TLS
}, /* for external TLS connections */
1892 /* Service list for TCP */
1893 static const struct sip_service_data service_tcp
[] = {
1894 { "sipinternal", "tcp", SIPE_TRANSPORT_TCP
}, /* for internal TCP connections */
1895 { "sip", "tcp", SIPE_TRANSPORT_TCP
}, /*.for external TCP connections */
1899 static const struct sip_service_data
*services
[] = {
1900 service_autodetect
, /* SIPE_TRANSPORT_AUTO */
1901 service_tls
, /* SIPE_TRANSPORT_TLS */
1902 service_tcp
/* SIPE_TRANSPORT_TCP */
1905 struct sip_address_data
{
1911 * Autodiscover using DNS A records. This is an extension addded
1912 * by Microsoft. See http://support.microsoft.com/kb/2619522
1914 static const struct sip_address_data addresses
[] = {
1915 { "sipinternal", 5061 },
1916 { "sipexternal", 443 },
1918 * Our implementation supports only one port per host name. If the host name
1919 * resolves OK, we abort the search and try to connect. If we would know if we
1920 * are trying to connect from "Intranet" or "Internet" then we could choose
1921 * between those two ports.
1923 * We drop port 5061 in order to cover the "Internet" case.
1931 static void sipe_core_dns_resolved(struct sipe_core_public
*sipe_public
,
1932 const gchar
*hostname
, guint port
)
1934 struct sipe_core_private
*sipe_private
= SIPE_CORE_PRIVATE
;
1935 gboolean service
= sipe_private
->service_data
!= NULL
;
1937 sipe_private
->dns_query
= NULL
;
1944 host
= g_strdup(hostname
);
1945 type
= sipe_private
->service_data
->type
;
1947 /* DNS A resolver returns an IP address */
1948 host
= g_strdup_printf("%s.%s",
1949 sipe_private
->address_data
->prefix
,
1950 sipe_private
->public.sip_domain
);
1951 port
= sipe_private
->address_data
->port
;
1952 type
= sipe_private
->transport_type
;
1953 if (type
== SIPE_TRANSPORT_AUTO
)
1954 type
= SIPE_TRANSPORT_TLS
;
1957 SIPE_DEBUG_INFO("sipe_core_dns_resolved - %s hostname: %s port: %d",
1958 service
? "SRV" : "A", hostname
, port
);
1959 sipe_server_register(sipe_private
, type
, host
, port
);
1962 resolve_next_service(SIPE_CORE_PRIVATE
, NULL
);
1964 resolve_next_address(SIPE_CORE_PRIVATE
, FALSE
);
1968 static void resolve_next_lync(struct sipe_core_private
*sipe_private
)
1970 struct sipe_lync_autodiscover_data
*lync_data
= sipe_private
->lync_autodiscover_servers
->data
;
1971 guint type
= sipe_private
->transport_type
;
1974 /* Try to connect to next server on the list */
1975 if (type
== SIPE_TRANSPORT_AUTO
)
1976 type
= SIPE_TRANSPORT_TLS
;
1978 sipe_server_register(sipe_private
,
1980 g_strdup(lync_data
->server
),
1984 /* We tried all servers -> try DNS SRV next */
1985 SIPE_LOG_INFO_NOFORMAT("no Lync Autodiscover servers found; trying SRV records next");
1986 resolve_next_service(sipe_private
, services
[type
]);
1989 sipe_private
->lync_autodiscover_servers
=
1990 sipe_lync_autodiscover_pop(sipe_private
->lync_autodiscover_servers
);
1993 static void resolve_next_service(struct sipe_core_private
*sipe_private
,
1994 const struct sip_service_data
*start
)
1997 sipe_private
->service_data
= start
;
1999 sipe_private
->service_data
++;
2000 if (sipe_private
->service_data
->protocol
== NULL
) {
2002 /* We tried all services */
2003 sipe_private
->service_data
= NULL
;
2005 /* Try A records list next */
2006 SIPE_LOG_INFO_NOFORMAT("no SRV records found; trying A records next");
2007 resolve_next_address(sipe_private
, TRUE
);
2012 /* Try to resolve next service */
2013 sipe_private
->dns_query
= sipe_backend_dns_query_srv(
2015 sipe_private
->service_data
->protocol
,
2016 sipe_private
->service_data
->transport
,
2017 sipe_private
->public.sip_domain
,
2018 (sipe_dns_resolved_cb
) sipe_core_dns_resolved
,
2022 static void resolve_next_address(struct sipe_core_private
*sipe_private
,
2028 sipe_private
->address_data
= addresses
;
2030 sipe_private
->address_data
++;
2031 if (sipe_private
->address_data
->prefix
== NULL
) {
2032 guint type
= sipe_private
->transport_type
;
2034 /* We tried all addresss */
2035 sipe_private
->address_data
= NULL
;
2037 /* Try connecting to the SIP hostname directly */
2038 SIPE_LOG_INFO_NOFORMAT("no SRV or A records found; using SIP domain as fallback");
2039 if (type
== SIPE_TRANSPORT_AUTO
)
2040 type
= SIPE_TRANSPORT_TLS
;
2042 sipe_server_register(sipe_private
, type
,
2043 g_strdup(sipe_private
->public.sip_domain
),
2049 /* Try to resolve next address */
2050 hostname
= g_strdup_printf("%s.%s",
2051 sipe_private
->address_data
->prefix
,
2052 sipe_private
->public.sip_domain
);
2053 sipe_private
->dns_query
= sipe_backend_dns_query_a(
2056 sipe_private
->address_data
->port
,
2057 (sipe_dns_resolved_cb
) sipe_core_dns_resolved
,
2062 static void lync_autodiscover_cb(struct sipe_core_private
*sipe_private
,
2064 SIPE_UNUSED_PARAMETER gpointer callback_data
)
2067 /* Lync Autodiscover succeeded */
2068 SIPE_DEBUG_INFO_NOFORMAT("lync_autodiscover_cb: got server list");
2070 sipe_private
->lync_autodiscover_servers
= servers
;
2071 resolve_next_lync(sipe_private
);
2076 * NOTE: this function can be called before sipe_core_allocate()!
2078 gboolean
sipe_core_transport_sip_requires_password(guint authentication
,
2081 return(sip_sec_requires_password(authentication
, sso
));
2084 void sipe_core_transport_sip_connect(struct sipe_core_public
*sipe_public
,
2086 guint authentication
,
2087 const gchar
*server
,
2090 struct sipe_core_private
*sipe_private
= SIPE_CORE_PRIVATE
;
2092 /* backend initialization is complete */
2093 sipe_core_backend_initialized(sipe_private
, authentication
);
2096 * Initializing the certificate sub-system will trigger the generation
2097 * of a cryptographic key pair which takes time. If we do this after we
2098 * have connected to the server then there is a risk that we run into a
2099 * SIP connection timeout. So let's get this out of the way now...
2101 * This is currently only needed if the user has selected TLS-DSK.
2103 if (sipe_private
->authentication_type
== SIPE_AUTHENTICATION_TYPE_TLS_DSK
)
2104 sipe_certificate_init(sipe_private
);
2107 /* Use user specified server[:port] */
2108 int port_number
= 0;
2111 port_number
= atoi(port
);
2113 SIPE_LOG_INFO("sipe_core_connect: user specified SIP server %s:%d",
2114 server
, port_number
);
2116 sipe_server_register(sipe_private
, transport
,
2117 g_strdup(server
), port_number
);
2119 /* Server auto-discovery */
2121 /* Remember user specified transport type */
2122 sipe_private
->transport_type
= transport
;
2124 /* Start with Lync Autodiscover first */
2125 sipe_lync_autodiscover_start(sipe_private
,
2126 lync_autodiscover_cb
,
2131 const gchar
*sipe_core_transport_sip_server_name(struct sipe_core_public
*sipe_public
)
2133 struct sip_transport
*transport
= SIPE_CORE_PRIVATE
->transport
;
2134 return(transport
? transport
->server_name
: NULL
);
2137 int sip_transaction_cseq(struct transaction
*trans
)
2141 g_return_val_if_fail(trans
&& trans
->key
, 0);
2143 sscanf(trans
->key
, "<%*[a-zA-Z0-9]><%d INVITE>", &cseq
);
2147 const gchar
*sip_transport_epid(struct sipe_core_private
*sipe_private
)
2149 return(sipe_private
->transport
?
2150 sipe_private
->transport
->epid
:
2154 const gchar
*sip_transport_ip_address(struct sipe_core_private
*sipe_private
)
2156 return(sipe_private
->transport
?
2157 sipe_private
->transport
->ip_address
:
2161 const gchar
*sip_transport_sdp_address_marker(struct sipe_core_private
*sipe_private
)
2163 return(sipe_private
->transport
?
2164 sipe_private
->transport
->sdp_marker
: