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