purple: work around broken dbus-server.h
[siplcs.git] / src / core / sipe-core.c
blobef01e10b18797701166d282edeff0b68d0dd6c2b
1 /**
2 * @file sipe-core.c
4 * pidgin-sipe
6 * Copyright (C) 2010-2017 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
23 * Some notes on the history of this project/code/copyrights:
25 * - the project is called SIPE, but originally the code was only written
26 * for the libpurple framework, i.e. Pidgin. Hence the package name is
27 * "pidgin-sipe".
29 * - in the beginning almost all of the code was located in a module
30 * called "sipe.c". During the effort to remove the libpurple
31 * dependencies from the SIPE core, thousands of lines of code got
32 * shifted out of sipe.c, mostly to newly created modules and sipe.c
33 * ceased to exist.
35 * - it would have been tedious to track down the original author or
36 * copyright and preserve them for each line of code that was moved.
37 * Therefore the new modules started with a fresh copyright notice
38 * (like the one above).
40 * - the original copyright notices from sipe.c have been moved to this
41 * file (see below) and *MUST* be preserved!
43 * - if necessary the author of a line of code in question can still be
44 * reconstructed from the git repository information.
45 * See also "man git-blame"
47 * - if you think your copyright should be restored for a piece of code,
48 * then please contact the SIPE project to fix the source files ASAP.
50 *------------------- Copyright notices from "sipe.c" ---------------
51 * Copyright (C) 2010-11 SIPE Project <http://sipe.sourceforge.net/>
52 * Copyright (C) 2009-10 pier11 <pier11@operamail.com>
53 * Copyright (C) 2008 Novell, Inc.
54 * Copyright (C) 2007-09 Anibal Avelar <debianmx@gmail.com>
55 * Copyright (C) 2005 Thomas Butter <butter@uni-mannheim.de>
57 * ***
58 * Thanks to Google's Summer of Code Program and the helpful mentors
59 * ***
60 *------------------- Copyright notices from "sipe.c" ---------------
63 #ifdef HAVE_CONFIG_H
64 #include "config.h"
65 #endif
67 #include <stdlib.h>
68 #include <string.h>
70 #include <glib.h>
72 #include "sipe-common.h"
73 #include "sip-csta.h"
74 #include "sip-sec.h"
75 #include "sip-transport.h"
76 #include "sipe-backend.h"
77 #include "sipe-buddy.h"
78 #include "sipe-cal.h"
79 #include "sipe-certificate.h"
80 #include "sipe-chat.h"
81 #include "sipe-conf.h"
82 #include "sipe-core.h"
83 #include "sipe-core-private.h"
84 #include "sipe-crypt.h"
85 #include "sipe-ews-autodiscover.h"
86 #include "sipe-group.h"
87 #include "sipe-groupchat.h"
88 #include "sipe-http.h"
89 #include "sipe-lync-autodiscover.h"
90 #include "sipe-media.h"
91 #include "sipe-mime.h"
92 #include "sipe-nls.h"
93 #include "sipe-ocs2007.h"
94 #include "sipe-schedule.h"
95 #include "sipe-session.h"
96 #include "sipe-status.h"
97 #include "sipe-subscriptions.h"
98 #include "sipe-svc.h"
99 #include "sipe-ucs.h"
100 #include "sipe-utils.h"
101 #include "sipe-webticket.h"
103 #ifdef PACKAGE_GIT_COMMIT
104 #define SIPE_CORE_VERSION PACKAGE_VERSION " (git commit " PACKAGE_GIT_COMMIT " / "
105 #else
106 #define SIPE_CORE_VERSION PACKAGE_VERSION " ("
107 #endif
109 /* translate config.h options to strings */
110 static const gchar * const sipe_core_build_options[] = {
112 /* Authentication */
113 #ifdef HAVE_SSPI
114 "SSPI",
115 #elif defined(HAVE_GSSAPI_ONLY)
116 "GSSAPI",
117 #ifndef HAVE_GSSAPI_PASSWORD_SUPPORT
118 "SSO only",
119 #endif
120 #else
121 #ifdef HAVE_GSSAPI_GSSAPI_H
122 "Kerberos 5 & NTLM",
123 #else
124 "NTLM",
125 #endif
126 #endif
128 /* D-Bus */
129 #ifdef HAVE_DBUS
130 "D-Bus",
131 #endif
133 /* Media */
134 #ifdef HAVE_VV
135 "Voice & Video",
136 #ifdef HAVE_SRTP
137 "SRTP",
138 #endif
139 #ifdef HAVE_XDATA
140 "Lync FT",
141 #endif
142 #ifdef HAVE_APPSHARE
143 "Application Sharing",
144 #endif
145 #endif
147 /* Development */
148 #ifdef HAVE_VALGRIND
149 "Valgrind",
150 #endif
152 NULL
156 /* locale_dir is unused if ENABLE_NLS is not defined */
157 void sipe_core_init(SIPE_UNUSED_PARAMETER const char *locale_dir)
159 srand(time(NULL));
160 sip_sec_init();
162 #ifdef ENABLE_NLS
163 SIPE_DEBUG_INFO("bindtextdomain = %s",
164 bindtextdomain(PACKAGE_NAME, locale_dir));
165 SIPE_DEBUG_INFO("bind_textdomain_codeset = %s",
166 bind_textdomain_codeset(PACKAGE_NAME, "UTF-8"));
167 textdomain(PACKAGE_NAME);
168 #endif
169 /* Initialization for crypto backend (production mode) */
170 sipe_crypto_init(TRUE);
171 sipe_mime_init();
172 sipe_status_init();
175 void sipe_core_destroy(void)
177 sipe_chat_destroy();
178 sipe_status_shutdown();
179 sipe_mime_shutdown();
180 sipe_crypto_shutdown();
181 sip_sec_destroy();
184 gchar *sipe_core_about(void)
186 gchar *options = g_strjoinv(" / ", (gchar **) sipe_core_build_options);
187 gchar *about = g_strdup_printf(
189 * Non-translatable parts, like markup, are hard-coded
190 * into the format string. This requires more translatable
191 * texts but it makes the translations less error prone.
193 "<b><font size=\"+1\">SIPE " SIPE_CORE_VERSION "%s) </font></b><br/>"
194 "<br/>"
195 /* 1 */ "%s:<br/>"
196 " - Skype for Business<br/>"
197 " - Microsoft Office 365<br/>"
198 " - Microsoft Business Productivity Online Suite (BPOS)<br/>"
199 " - Microsoft Lync Server<br/>"
200 " - Microsoft Office Communications Server 2007 R2<br/>"
201 " - Microsoft Office Communications Server 2007<br/>"
202 " - Microsoft Live Communications Server 2005<br/>"
203 " - Microsoft Live Communications Server 2003<br/>"
204 "<br/>"
205 /* 2 */ "%s: <a href=\"" PACKAGE_URL "\">" PACKAGE_URL "</a><br/>"
206 /* 3,4 */ "%s: <a href=\"http://sourceforge.net/p/sipe/discussion/688534/\">%s</a><br/>"
207 /* 5,6 */ "%s: <a href=\"" PACKAGE_BUGREPORT "\">%s</a><br/>"
208 /* 7 */ "%s: <a href=\"" SIPE_TRANSLATIONS_URL "\">Transifex.com</a><br/>"
209 /* 8 */ "%s: GPLv2+<br/>"
210 "<br/>"
211 /* 9 (REMOVED) */
212 /* 10,11 */ "%s<a href=\"" SIPE_TRANSLATIONS_URL "\">Transifex.com</a>%s.<br/>"
213 "<br/>"
214 /* 12 */ "<b>%s:</b><br/>"
215 " - Stefan Becker<br/>"
216 " - Jakub Adam<br/>"
217 " - Jochen De Smet (retired, Miranda port)<br/>"
218 " - Michael Lamb (retired, Adium port)<br/>"
219 " - Anibal Avelar (retired)<br/>"
220 " - Gabriel Burt (retired)<br/>"
221 " - pier11 (retired)<br/>"
222 " - Tomáš Hrabčík (retired)<br/>"
223 "<br/>"
224 /* 13 */ "%s<br/>"
225 , options,
226 /* The next 13 texts make up the SIPE about note text */
227 /* About note, part 1/13: introduction */
228 _("A third-party plugin implementing extended version of SIP/SIMPLE used by various products"),
229 /* About note, part 2/13: home page URL (label) */
230 _("Home Page"),
231 /* About note, part 3/13: support forum URL (label) */
232 _("Support"),
233 /* About note, part 4/13: support forum name (hyperlink text) */
234 _("Help Forum"),
235 /* About note, part 5/13: bug tracker URL (label) */
236 _("Report Problems"),
237 /* About note, part 6/13: bug tracker URL (hyperlink text) */
238 _("Bug Tracker"),
239 /* About note, part 7/13: translation service URL (label) */
240 _("Translations"),
241 /* About note, part 8/13: license type (label) */
242 _("License"),
243 /* About note, part 9/13: (REMOVED) */
244 /* About note, part 10/13: translation request, text before Transifex.com URL */
245 /* append a space if text is not empty */
246 _("Please help us to translate SIPE to your native language here at "),
247 /* About note, part 11/13: translation request, text after Transifex.com URL */
248 /* start with a space if text is not empty */
249 _(" using convenient web interface"),
250 /* About note, part 12/13: author list (header) */
251 _("Authors"),
252 /* About note, part 13/13: Localization credit */
253 /* PLEASE NOTE: do *NOT* simply translate the english original */
254 /* but write something similar to the following sentence: */
255 /* "Localization for <language name> (<language code>): <name>" */
256 _("Original texts in English (en): SIPE developers")
258 g_free(options);
259 return(about);
262 struct sipe_core_public *sipe_core_allocate(const gchar *signin_name,
263 gboolean sso,
264 const gchar *login_account,
265 const gchar *password,
266 const gchar *email,
267 const gchar *email_url,
268 const gchar **errmsg)
270 struct sipe_core_private *sipe_private;
271 gchar **user_domain;
272 gchar *options = g_strjoinv(" / ", (gchar **) sipe_core_build_options);
274 SIPE_LOG_INFO("sipe_core_allocate: SIPE version " SIPE_CORE_VERSION "%s)", options);
275 g_free(options);
276 SIPE_DEBUG_INFO("sipe_core_allocate: signin_name '%s'", signin_name);
278 /* ensure that sign-in name doesn't contain invalid characters */
279 if (strpbrk(signin_name, "\t\v\r\n") != NULL) {
280 *errmsg = _("SIP Exchange user name contains invalid characters");
281 return NULL;
284 /* ensure that sign-in name format is name@domain */
285 if (!strchr(signin_name, '@') ||
286 g_str_has_prefix(signin_name, "@") ||
287 g_str_has_suffix(signin_name, "@")) {
288 *errmsg = _("User name should be a valid SIP URI\nExample: user@company.com");
289 return NULL;
293 /* ensure that Password is valid when SSO is not selected */
294 if (!sso && is_empty(password)) {
295 *errmsg = _("Password is required when Single Sign-On is not enabled");
296 return NULL;
299 /* ensure that email format is name@domain (if provided) */
300 if (!is_empty(email) &&
301 (!strchr(email, '@') ||
302 g_str_has_prefix(email, "@") ||
303 g_str_has_suffix(email, "@")))
305 *errmsg = _("Email address should be valid if provided\nExample: user@company.com");
306 return NULL;
309 /* ensure that user name doesn't contain spaces */
310 user_domain = g_strsplit(signin_name, "@", 2);
311 SIPE_DEBUG_INFO("sipe_core_allocate: user '%s' domain '%s'", user_domain[0], user_domain[1]);
312 if (strchr(user_domain[0], ' ') != NULL) {
313 g_strfreev(user_domain);
314 *errmsg = _("SIP Exchange user name contains whitespace");
315 return NULL;
318 /* ensure that email_url is in proper format if enabled (if provided).
319 * Example (Exchange): https://server.company.com/EWS/Exchange.asmx
320 * Example (Domino) : https://[domino_server]/[mail_database_name].nsf
322 if (!is_empty(email_url)) {
323 char *tmp = g_ascii_strdown(email_url, -1);
324 if (!g_str_has_prefix(tmp, "https://"))
326 g_free(tmp);
327 g_strfreev(user_domain);
328 *errmsg = _("Email services URL should be valid if provided\n"
329 "Example: https://exchange.corp.com/EWS/Exchange.asmx\n"
330 "Example: https://domino.corp.com/maildatabase.nsf");
331 return NULL;
333 g_free(tmp);
336 /* re-use sign-in name if login is empty */
337 if (is_empty(login_account))
338 login_account = signin_name;
340 sipe_private = g_new0(struct sipe_core_private, 1);
341 SIPE_CORE_PRIVATE_FLAG_UNSET(SUBSCRIBED_BUDDIES);
342 SIPE_CORE_PRIVATE_FLAG_UNSET(INITIAL_PUBLISH);
343 SIPE_CORE_PRIVATE_FLAG_UNSET(SSO);
344 if (sso)
345 SIPE_CORE_PRIVATE_FLAG_SET(SSO);
346 sipe_private->username = g_strdup(signin_name);
347 sipe_private->email = is_empty(email) ? g_strdup(signin_name) : g_strdup(email);
348 sipe_private->authuser = sso ? NULL : g_strdup(login_account);
349 sipe_private->password = sso ? NULL : g_strdup(password);
350 sipe_private->public.sip_name = g_strdup(user_domain[0]);
351 sipe_private->public.sip_domain = g_strdup(user_domain[1]);
352 g_strfreev(user_domain);
354 sipe_group_init(sipe_private);
355 sipe_buddy_init(sipe_private);
356 sipe_private->our_publications = g_hash_table_new_full(g_str_hash, g_str_equal,
357 g_free, (GDestroyNotify)g_hash_table_destroy);
358 sipe_subscriptions_init(sipe_private);
359 sipe_lync_autodiscover_init(sipe_private);
360 sipe_ews_autodiscover_init(sipe_private);
361 sipe_status_set_activity(sipe_private, SIPE_ACTIVITY_UNSET);
363 sipe_private->media_calls = g_hash_table_new_full(g_str_hash, g_str_equal,
364 g_free, NULL);
365 sipe_private->access_numbers = g_hash_table_new_full(g_str_hash, g_str_equal,
366 g_free, g_free);
368 return((struct sipe_core_public *)sipe_private);
371 void sipe_core_backend_initialized(struct sipe_core_private *sipe_private,
372 guint authentication)
374 const gchar *value;
376 sipe_private->authentication_type = authentication;
378 /* user specified email login? */
379 value = sipe_backend_setting(SIPE_CORE_PUBLIC, SIPE_SETTING_EMAIL_LOGIN);
380 if (!is_empty(value)) {
381 sipe_private->email_authuser = g_strdup(value);
382 sipe_private->email_password = g_strdup(sipe_backend_setting(SIPE_CORE_PUBLIC,
383 SIPE_SETTING_EMAIL_PASSWORD));
387 void sipe_core_connection_cleanup(struct sipe_core_private *sipe_private)
389 sipe_http_free(sipe_private);
390 sip_transport_disconnect(sipe_private);
392 sipe_schedule_cancel_all(sipe_private);
394 if (sipe_private->allowed_events)
395 sipe_utils_slist_free_full(sipe_private->allowed_events, g_free);
397 sipe_ocs2007_free(sipe_private);
399 sipe_core_buddy_menu_free(SIPE_CORE_PUBLIC);
401 if (sipe_private->contact)
402 g_free(sipe_private->contact);
403 sipe_private->contact = NULL;
404 if (sipe_private->register_callid)
405 g_free(sipe_private->register_callid);
406 sipe_private->register_callid = NULL;
408 if (sipe_private->focus_factory_uri)
409 g_free(sipe_private->focus_factory_uri);
410 sipe_private->focus_factory_uri = NULL;
412 sipe_groupchat_free(sipe_private);
414 while (sipe_private->lync_autodiscover_servers)
415 sipe_private->lync_autodiscover_servers =
416 sipe_lync_autodiscover_pop(sipe_private->lync_autodiscover_servers);
419 void sipe_core_deallocate(struct sipe_core_public *sipe_public)
421 struct sipe_core_private *sipe_private = SIPE_CORE_PRIVATE;
423 #ifdef HAVE_VV
424 sipe_media_handle_going_offline(sipe_private);
425 #endif
427 /* leave all conversations */
428 if (sipe_private->sessions) {
429 GSList *entry;
430 while ((entry = sipe_private->sessions) != NULL) {
431 sipe_session_close(sipe_private, entry->data);
435 sipe_conf_cancel_unaccepted(sipe_private, NULL);
437 if (sipe_private->csta) {
438 sip_csta_close(sipe_private);
441 /* pending service requests must be cancelled first */
442 sipe_svc_free(sipe_private);
443 sipe_webticket_free(sipe_private);
444 sipe_ucs_free(sipe_private);
445 sipe_lync_autodiscover_free(sipe_private);
447 if (sipe_backend_connection_is_valid(SIPE_CORE_PUBLIC)) {
448 sipe_subscriptions_unsubscribe(sipe_private);
449 sip_transport_deregister(sipe_private);
452 sipe_core_connection_cleanup(sipe_private);
453 sipe_ews_autodiscover_free(sipe_private);
454 sipe_cal_calendar_free(sipe_private->calendar);
455 sipe_certificate_free(sipe_private);
457 g_free(sipe_private->public.sip_name);
458 g_free(sipe_private->public.sip_domain);
459 g_free(sipe_private->username);
460 g_free(sipe_private->email_password);
461 g_free(sipe_private->email_authuser);
462 g_free(sipe_private->email);
463 g_free(sipe_private->password);
464 g_free(sipe_private->authuser);
465 g_free(sipe_private->status);
466 g_free(sipe_private->note);
467 g_free(sipe_private->ocs2005_user_states);
469 sipe_buddy_free(sipe_private);
470 g_hash_table_destroy(sipe_private->our_publications);
471 g_hash_table_destroy(sipe_private->user_state_publications);
472 g_hash_table_destroy(sipe_private->media_calls);
473 sipe_subscriptions_destroy(sipe_private);
474 sipe_group_free(sipe_private);
476 if (sipe_private->our_publication_keys)
477 sipe_utils_slist_free_full(sipe_private->our_publication_keys, g_free);
479 #ifdef HAVE_VV
480 g_free(sipe_private->test_call_bot_uri);
481 g_free(sipe_private->uc_line_uri);
482 g_free(sipe_private->mras_uri);
483 g_free(sipe_private->media_relay_username);
484 g_free(sipe_private->media_relay_password);
485 sipe_media_relay_list_free(sipe_private->media_relays);
486 #endif
488 g_free(sipe_private->persistentChatPool_uri);
489 g_free(sipe_private->addressbook_uri);
490 g_free(sipe_private->dlx_uri);
491 sipe_utils_slist_free_full(sipe_private->conf_mcu_types, g_free);
492 g_hash_table_destroy(sipe_private->access_numbers);
493 g_free(sipe_private);
496 void sipe_core_email_authentication(struct sipe_core_private *sipe_private,
497 struct sipe_http_request *request)
499 if (sipe_private->email_authuser) {
500 sipe_http_request_authentication(request,
501 sipe_private->email_authuser,
502 sipe_private->email_password);
507 Local Variables:
508 mode: c
509 c-file-style: "bsd"
510 indent-tabs-mode: t
511 tab-width: 8
512 End: