libpurple/tls-certificate.c

branch
purple-ssl-to-gio
changeset 37620
5467197bd084
child 37621
2a2f1068e0f0
equal deleted inserted replaced
37561:06be9b727216 37620:5467197bd084
1 /*
2 *
3 * purple
4 *
5 * Purple is the legal property of its developers, whose names are too numerous
6 * to list here. Please refer to the COPYRIGHT file distributed with this
7 * source distribution.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
22 */
23
24 #include "internal.h"
25 #include "tls-certificate.h"
26 #include "debug.h"
27 #include "util.h"
28
29 /* Makes a filename path for a certificate. If id is NULL,
30 * just return the directory
31 */
32 static gchar *
33 make_certificate_path(const gchar *id)
34 {
35 return g_build_filename(purple_user_dir(),
36 "certificates", "tls",
37 id != NULL ? purple_escape_filename(id) : NULL,
38 NULL);
39 }
40
41 /* Creates the certificate directory if it doesn't exist,
42 * returns TRUE if it's successful or it already exists,
43 * returns FALSE if there was an error.
44 */
45 static gboolean
46 ensure_certificate_dir(GError **error)
47 {
48 gchar *dir = make_certificate_path(NULL);
49 gboolean ret = TRUE;
50
51 if (purple_build_dir(dir, 0700) != 0) {
52 g_set_error_literal(error, G_FILE_ERROR,
53 g_file_error_from_errno(errno),
54 g_strerror(errno));
55 ret = FALSE;
56 }
57
58 g_free(dir);
59 return ret;
60 }
61
62 GList *
63 purple_tls_certificate_list_ids()
64 {
65 gchar *dir_path;
66 GDir *dir;
67 const gchar *entry;
68 GList *idlist = NULL;
69 GError *error = NULL;
70
71 /* Ensure certificate directory exists */
72
73 if (!ensure_certificate_dir(&error)) {
74 purple_debug_error("tls-certificate",
75 "Error creating certificate directory: %s",
76 error->message);
77 g_clear_error(&error);
78 return NULL;
79 }
80
81 /* Open certificate directory */
82
83 dir_path = make_certificate_path(NULL);
84 dir = g_dir_open(dir_path, 0, &error);
85
86 if (dir == NULL) {
87 purple_debug_error("tls-certificate",
88 "Error opening certificate directory (%s): %s",
89 dir_path, error->message);
90 g_free(dir_path);
91 g_clear_error(&error);
92 return NULL;
93 }
94
95 g_free(dir_path);
96
97 /* Traverse the directory listing and create an idlist */
98
99 while ((entry = g_dir_read_name(dir)) != NULL) {
100 /* Unescape the filename
101 * (GLib owns original string)
102 */
103 const char *unescaped = purple_unescape_filename(entry);
104
105 /* Copy the entry name into our list
106 * (Purple own the escaped string)
107 */
108 idlist = g_list_prepend(idlist, g_strdup(unescaped));
109 }
110
111 g_dir_close(dir);
112
113 return idlist;
114 }
115
116 void
117 purple_tls_certificate_free_ids(GList *ids)
118 {
119 g_list_free_full(ids, g_free);
120 }
121
122 GTlsCertificate *
123 purple_tls_certificate_new_from_id(const gchar *id, GError **error)
124 {
125 GTlsCertificate *cert;
126 gchar *path;
127
128 g_return_val_if_fail(id != NULL && id[0] != '\0', NULL);
129
130 /* Load certificate from file if it exists */
131
132 path = make_certificate_path(id);
133 cert = g_tls_certificate_new_from_file(path, error);
134 g_free(path);
135
136 return cert;
137 }
138
139 gboolean
140 purple_tls_certificate_trust(const gchar *id, GTlsCertificate *certificate,
141 GError **error)
142 {
143 gchar *path;
144 gchar *pem = NULL;
145 gboolean ret;
146
147 g_return_val_if_fail(id != NULL && id[0] != '\0', FALSE);
148 g_return_val_if_fail(G_IS_TLS_CERTIFICATE(certificate), FALSE);
149
150 /* Ensure certificate directory exists */
151
152 if (!ensure_certificate_dir(error)) {
153 return FALSE;
154 }
155
156 /* Get the text representation of the certificate */
157
158 g_object_get(certificate, "certificate-pem", &pem, NULL);
159 g_return_val_if_fail(pem != NULL, FALSE);
160
161 /* Save certificate text to a fail */
162
163 path = make_certificate_path(id);
164 ret = g_file_set_contents(path, pem, -1, error);
165 g_free(path);
166 g_free(pem);
167
168 return ret;
169 }
170
171 gboolean
172 purple_tls_certificate_distrust(const gchar *id, GError **error)
173 {
174 gchar *path;
175 gboolean ret = TRUE;
176
177 g_return_val_if_fail(id != NULL && id[0] != '\0', FALSE);
178
179 /* Delete certificate file if it exists */
180
181 path = make_certificate_path(id);
182
183 if (g_unlink(path) != 0) {
184 g_set_error_literal(error, G_FILE_ERROR,
185 g_file_error_from_errno(errno),
186 g_strerror(errno));
187 ret = FALSE;
188 }
189
190 g_free(path);
191
192 return ret;
193 }
194

mercurial