1 /*
2  * Seahorse
3  *
4  * Copyright (C) 2007 Stef Walter
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14  * See the GNU General Public License for more details.
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 #include "config.h"
20 
21 #include <stdlib.h>
22 #include <string.h>
23 
24 #include <glib.h>
25 
26 #include <gnome-keyring-memory.h>
27 
28 #include "seahorse-secure-memory.h"
29 
30   /* extern declared in seahorse-secure-memory.h */
31   gboolean seahorse_use_secure_mem = FALSE;
32 
33 /**
34  * switch_malloc:
35  * @size: The size of the new memory buffer
36  *
37  * Transparent alternative. Depending on the setting for secure memory, the
38  * function calls the default-C version or the GTK version for non-pageable memory
39  *
40  * Returns: The pointer to the new buffer
41  */
42 static gpointer
switch_malloc(gsize size)43 switch_malloc (gsize size)
44 {
45     gpointer p;
46 
47     if (size == 0)
48         return NULL;
49     if (seahorse_use_secure_mem)
50         p = gnome_keyring_memory_try_alloc (size);
51     else
52         p = malloc (size);
53     return p;
54 }
55 
56 /**
57  * switch_calloc:
58  * @num: Number of blocks to allocate
59  * @size: Size of a block
60  *
61  * Transparent alternative. Depending on the setting for secure memory, the
62  * function calls the default-C version or the GTK version for non-pageable memory
63  *
64  * Returns: The pointer to a buffer sized num*size
65  */
66 static gpointer
switch_calloc(gsize num,gsize size)67 switch_calloc (gsize num, gsize size)
68 {
69     gpointer p;
70 
71     if (size == 0 || num == 0)
72         return NULL;
73     if (seahorse_use_secure_mem)
74         p = gnome_keyring_memory_try_alloc (size * num);
75     else
76         p = calloc (num, size);
77     return p;
78 }
79 
80 /**
81  * switch_realloc:
82  * @mem: The old memory to resize
83  * @size: The new size
84  *
85  * Transparent alternative. Depending on the setting for secure memory, the
86  * function calls the default-C version or the GTK version for non-pageable memory
87  *
88  * Returns: The pointer to the resized memory
89  */
90 static gpointer
switch_realloc(gpointer mem,gsize size)91 switch_realloc (gpointer mem, gsize size)
92 {
93     gpointer p;
94 
95     if (size == 0) {
96         free (mem);
97         return NULL;
98     }
99 
100     if (!mem) {
101         if (seahorse_use_secure_mem)
102             p = gnome_keyring_memory_alloc (size);
103         else
104             p = malloc (size);
105     } else if (gnome_keyring_memory_is_secure (mem))
106         p = gnome_keyring_memory_try_realloc (mem, size);
107     else
108         p = realloc (mem, size);
109     return p;
110 }
111 
112 /**
113  * switch_free:
114  * @mem: The memory to free
115  *
116  * Transparent alternative. Depending on the setting for secure memory, the
117  * function calls the default-C version or the GTK version for non-pageable memory
118  */
119 static void
switch_free(gpointer mem)120 switch_free (gpointer mem)
121 {
122     if (mem) {
123         if (gnome_keyring_memory_is_secure (mem))
124             gnome_keyring_memory_free (mem);
125         else
126             free (mem);
127     }
128 }
129 
130 /**
131  * seahorse_try_gk_secure_memory:
132  *
133  *
134  * Returns: TRUE if non-pageable memory is available
135  */
136 static gboolean
seahorse_try_gk_secure_memory()137 seahorse_try_gk_secure_memory ()
138 {
139     gpointer p;
140 
141     p = gnome_keyring_memory_try_alloc (10);
142     if (p != NULL) {
143         gnome_keyring_memory_free (p);
144         return TRUE;
145     }
146 
147     return FALSE;
148 }
149 
150 /**
151  * seahorse_secure_memory_init:
152  *
153  * Configures non-pageable (secure) memory. Must be called before the first
154  * memory allocation.
155  *
156  * This function sets the #GMemVTable to use the switch* function implemented in
157  * this files
158  *
159  */
160 void
seahorse_secure_memory_init()161 seahorse_secure_memory_init ()
162 {
163     if (seahorse_try_gk_secure_memory() == TRUE) {
164         GMemVTable vtable;
165 
166         memset (&vtable, 0, sizeof (vtable));
167         vtable.malloc = switch_malloc;
168         vtable.realloc = switch_realloc;
169         vtable.free = switch_free;
170         vtable.calloc = switch_calloc;
171         g_mem_set_vtable (&vtable);
172     } else {
173         g_warning ("Unable to allocate secure memory from gnome-keyring.\n");
174         g_warning ("Proceeding using insecure memory for password fields.\n");
175     }
176 }
177