1 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * Copyright (C) 2003-2006 Imendio AB
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public License as
7 * published by the Free Software Foundation; either version 2 of the
8 * License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this program; if not, see <https://www.gnu.org/licenses>
17 */
18
19 #include <config.h>
20
21 #include "lm-ssl.h"
22 #include "lm-ssl-base.h"
23 #include "lm-ssl-internals.h"
24
25 LmSSLResponse
_lm_ssl_func_always_continue(LmSSL * ssl,LmSSLStatus status,gpointer user_data)26 _lm_ssl_func_always_continue (LmSSL *ssl,
27 LmSSLStatus status,
28 gpointer user_data)
29 {
30 return LM_SSL_RESPONSE_CONTINUE;;
31 }
32
33 /* Define the SSL functions as noops if we compile without support */
34 #ifndef HAVE_SSL
35
36 LmSSL *
_lm_ssl_new(const gchar * expected_fingerprint,LmSSLFunction ssl_function,gpointer user_data,GDestroyNotify notify)37 _lm_ssl_new (const gchar *expected_fingerprint,
38 LmSSLFunction ssl_function,
39 gpointer user_data,
40 GDestroyNotify notify)
41 {
42 return NULL;
43 }
44
45 void
_lm_ssl_initialize(LmSSL * ssl)46 _lm_ssl_initialize (LmSSL *ssl)
47 {
48 /* NOOP */
49 }
50
51 gboolean
_lm_ssl_begin(LmSSL * ssl,gint fd,const gchar * server,GError ** error)52 _lm_ssl_begin (LmSSL *ssl,
53 gint fd,
54 const gchar *server,
55 GError **error)
56 {
57 return TRUE;
58 }
59
60 GIOStatus
_lm_ssl_read(LmSSL * ssl,gchar * buf,gint len,gsize * bytes_read)61 _lm_ssl_read (LmSSL *ssl,
62 gchar *buf,
63 gint len,
64 gsize *bytes_read)
65 {
66 /* NOOP */
67 *bytes_read = 0;
68
69 return G_IO_STATUS_EOF;
70 }
71
72 gboolean
_lm_ssl_send(LmSSL * ssl,const gchar * str,gint len)73 _lm_ssl_send (LmSSL *ssl, const gchar *str, gint len)
74 {
75 /* NOOP */
76 return TRUE;
77 }
78 void
_lm_ssl_close(LmSSL * ssl)79 _lm_ssl_close (LmSSL *ssl)
80 {
81 /* NOOP */
82 }
83
84 void
_lm_ssl_free(LmSSL * ssl)85 _lm_ssl_free (LmSSL *ssl)
86 {
87 /* NOOP */
88 }
89
90 #endif /* HAVE_SSL */
91
92
93 /**
94 * lm_ssl_new:
95 * @expected_fingerprint: The expected fingerprint. @ssl_function will be called if there is a mismatch. %NULL if you are not interested in this check.
96 * @ssl_function: Callback called to inform the user of a problem during setting up the SSL connection and how to proceed. If %NULL is passed the default function that always continues will be used.
97 * @user_data: Data sent with the callback.
98 * @notify: Function to free @user_dataa when the connection is finished. %NULL if @user_data should not be freed.
99 *
100 * Creates a new SSL struct, call #lm_connection_set_ssl to use it.
101 *
102 * Return value: A new #LmSSL struct.
103 **/
104 LmSSL *
lm_ssl_new(const gchar * expected_fingerprint,LmSSLFunction ssl_function,gpointer user_data,GDestroyNotify notify)105 lm_ssl_new (const gchar *expected_fingerprint,
106 LmSSLFunction ssl_function,
107 gpointer user_data,
108 GDestroyNotify notify)
109 {
110 /* The implementation of this function will be different depending
111 * on which implementation is used
112 */
113 return _lm_ssl_new (expected_fingerprint,
114 ssl_function, user_data, notify);
115 }
116
117 /**
118 * lm_ssl_is_supported:
119 *
120 * Checks whether Loudmouth supports SSL or not.
121 *
122 * Return value: #TRUE if this installation of Loudmouth supports SSL, otherwise returns #FALSE.
123 **/
124 gboolean
lm_ssl_is_supported(void)125 lm_ssl_is_supported (void)
126 {
127 #ifdef HAVE_SSL
128 return TRUE;
129 #else
130 return FALSE;
131 #endif
132 }
133
134
135 /**
136 * lm_ssl_get_fingerprint:
137 * @ssl: an #LmSSL
138 *
139 * Returns the fingerprint of the remote server's certificate.
140 *
141 * Return value: A null terminated string representing the fingerprint or %NULL if unknown.
142 **/
143 const gchar *
lm_ssl_get_fingerprint(LmSSL * ssl)144 lm_ssl_get_fingerprint (LmSSL *ssl)
145 {
146 g_return_val_if_fail (ssl != NULL, NULL);
147
148 return LM_SSL_BASE(ssl)->fingerprint;
149 }
150
151 /**
152 * lm_ssl_ref:
153 * @ssl: an #LmSSL
154 *
155 * Adds a reference to @ssl.
156 *
157 * Return value: the ssl
158 **/
159 LmSSL *
lm_ssl_ref(LmSSL * ssl)160 lm_ssl_ref (LmSSL *ssl)
161 {
162 g_return_val_if_fail (ssl != NULL, NULL);
163
164 LM_SSL_BASE(ssl)->ref_count++;
165
166 return ssl;
167 }
168
169 /**
170 * lm_ssl_set_cipher_list:
171 * @ssl: an #LmSSL
172 * @cipher_list: list of ciphers
173 *
174 * Sets the list of availeble ciphers.
175 *
176 **/
177 void
lm_ssl_set_cipher_list(LmSSL * ssl,const gchar * cipher_list)178 lm_ssl_set_cipher_list (LmSSL *ssl,
179 const gchar *cipher_list)
180 {
181 _lm_ssl_base_set_cipher_list(LM_SSL_BASE(ssl), cipher_list);
182 }
183
184 /**
185 * lm_ssl_set_ca:
186 * @ssl: an #LmSSL
187 * @ca_path: path to a certificate or a directory containing certificates
188 *
189 * Sets a path to certificates which should be trusted.
190 *
191 **/
192 void
lm_ssl_set_ca(LmSSL * ssl,const gchar * ca_path)193 lm_ssl_set_ca (LmSSL *ssl, const gchar *ca_path)
194 {
195 _lm_ssl_base_set_ca_path(LM_SSL_BASE(ssl), ca_path);
196 }
197
198
199 /**
200 * lm_ssl_use_starttls:
201 * @ssl: an #LmSSL
202 *
203 * Set whether STARTTLS should be used.
204 **/
205 void
lm_ssl_use_starttls(LmSSL * ssl,gboolean use_starttls,gboolean require_starttls)206 lm_ssl_use_starttls (LmSSL *ssl,
207 gboolean use_starttls,
208 gboolean require_starttls)
209 {
210 LmSSLBase *base;
211
212 base = LM_SSL_BASE (ssl);
213 base->use_starttls = use_starttls;
214 base->require_starttls = require_starttls;
215 }
216
217 /**
218 * lm_ssl_get_use_starttls:
219 *
220 * Return value: TRUE is @ssl is configured to use STARTTLS.
221 **/
222 gboolean
lm_ssl_get_use_starttls(LmSSL * ssl)223 lm_ssl_get_use_starttls (LmSSL *ssl)
224 {
225 LmSSLBase *base;
226
227 base = LM_SSL_BASE (ssl);
228 return base->use_starttls;
229 }
230
231 /**
232 * lm_ssl_get_require_starttls:
233 *
234 * Return value: TRUE if @ssl requires that STARTTLS succeed.
235 **/
236 gboolean
lm_ssl_get_require_starttls(LmSSL * ssl)237 lm_ssl_get_require_starttls (LmSSL *ssl)
238 {
239 LmSSLBase *base;
240
241 base = LM_SSL_BASE (ssl);
242 return base->require_starttls;
243 }
244
245 /**
246 * lm_ssl_unref
247 * @ssl: an #LmSSL
248 *
249 * Removes a reference from @ssl. When no more references are present
250 * @ssl is freed.
251 **/
252 void
lm_ssl_unref(LmSSL * ssl)253 lm_ssl_unref (LmSSL *ssl)
254 {
255 LmSSLBase *base;
256
257 g_return_if_fail (ssl != NULL);
258
259 base = LM_SSL_BASE (ssl);
260
261 base->ref_count --;
262
263 if (base->ref_count == 0) {
264 if (base->data_notify) {
265 (* base->data_notify) (base->func_data);
266 }
267
268 _lm_ssl_free (ssl);
269 }
270 }
271
272
273