OpenVAS Libraries  9.0.3
gpgme_util.c
Go to the documentation of this file.
1 /* openvas-libraries/base
2  * $Id$
3  * Description: GPGME utilities.
4  *
5  * Authors:
6  * Bernhard Herzog <bernhard.herzog@intevation.de>
7  * Werner Koch <wk@gnupg.org>
8  *
9  * Copyright:
10  * Copyright (C) 2009,2013 Greenbone Networks GmbH
11  *
12  * This program is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU General Public License
14  * as published by the Free Software Foundation; either version 2
15  * of the License, or (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
25  */
26 
32 #include <assert.h>
33 #include <ctype.h>
34 #include <glib.h>
35 #include <stdlib.h>
36 #include <locale.h> /* for LC_CTYPE */
37 #include <unistd.h> /* for F_OK */
38 #include <sys/stat.h> /* for mkdir */
39 #include <errno.h> /* for ENOENT */
40 
41 #include "gpgme_util.h"
42 
43 #undef G_LOG_DOMAIN
44 
47 #define G_LOG_DOMAIN "base gpgme"
48 
49 static char *gpghome = NULL;
50 
67 static void
68 log_gpgme (GLogLevelFlags level, gpg_error_t err, const char *fmt, ...)
69 {
70  va_list arg_ptr;
71  char *msg;
72 
73  va_start (arg_ptr, fmt);
74  msg = g_strdup_vprintf (fmt, arg_ptr);
75  va_end (arg_ptr);
76  if (err && gpg_err_source (err) != GPG_ERR_SOURCE_ANY
77  && gpg_err_source (err))
78  g_log (G_LOG_DOMAIN, level, "%s: %s <%s>",
79  msg, gpg_strerror (err), gpg_strsource (err));
80  else if (err)
81  g_log (G_LOG_DOMAIN, level, "%s: %s",
82  msg, gpg_strerror (err));
83  else
84  g_log (G_LOG_DOMAIN, level, "%s",
85  msg);
86  g_free (msg);
87 }
88 
101 gpgme_ctx_t
103 {
104  static int initialized;
105  gpgme_error_t err;
106  gpgme_ctx_t ctx;
107 
108  /* Initialize GPGME the first time we are called. This is a
109  failsafe mode; it would be better to initialize GPGME early at
110  process startup instead of this on-the-fly method; however in
111  this non-threaded system; this is an easier way for a library.
112  We allow to initialize until a valid gpgme or a gpg backend has
113  been found. */
114  if (!initialized)
115  {
116  gpgme_engine_info_t info;
117 
118  if (!gpgme_check_version (NULL))
119  {
120  g_critical ("gpgme library could not be initialized.");
121  return NULL;
122  }
123  gpgme_set_locale (NULL, LC_CTYPE, setlocale (LC_CTYPE, NULL));
124 # ifdef LC_MESSAGES
125  gpgme_set_locale (NULL, LC_MESSAGES, setlocale (LC_MESSAGES, NULL));
126 # endif
127 
128 #ifndef NDEBUG
129  g_message ("Setting GnuPG dir to '%s'", dir);
130 #endif
131  err = 0;
132  if (access (dir, F_OK))
133  {
134  err = gpg_error_from_syserror ();
135 
136  if (errno == ENOENT)
137  /* directory does not exists. try to create it */
138  if (mkdir (dir, 0700) == 0)
139  {
140 #ifndef NDEBUG
141  g_message ("Created GnuPG dir '%s'", dir);
142 #endif
143  err = 0;
144  }
145  }
146 
147  if (!err)
148  err = gpgme_set_engine_info (GPGME_PROTOCOL_OpenPGP, NULL, dir);
149 
150  if (err)
151  {
152  log_gpgme (G_LOG_LEVEL_WARNING, err, "Setting GnuPG dir failed");
153  return NULL;
154  }
155 
156  /* Show the OpenPGP engine version. */
157  if (!gpgme_get_engine_info (&info))
158  {
159  while (info && info->protocol != GPGME_PROTOCOL_OpenPGP)
160  info = info->next;
161  }
162  else
163  info = NULL;
164 #ifndef NDEBUG
165  g_message ("Using OpenPGP engine version '%s'",
166  info && info->version? info->version: "[?]");
167 #endif
168 
169  /* Everything is fine. */
170  initialized = 1;
171  }
172 
173  /* Allocate the context. */
174  ctx = NULL;
175  err = gpgme_new (&ctx);
176  if (err)
177  log_gpgme (G_LOG_LEVEL_WARNING, err, "Creating GPGME context failed");
178 
179  return ctx;
180 }
181 
197 static char *
198 determine_gpghome (const gchar *subdir)
199 {
200  char *envdir = getenv ("OPENVAS_GPGHOME");
201 
202  if (envdir)
203  return g_strdup (envdir);
204  if (subdir)
205  return g_build_filename (OPENVAS_STATE_DIR, subdir, "gnupg", NULL);
206  return g_build_filename (OPENVAS_STATE_DIR, "gnupg", NULL);
207 }
208 
223 gpgme_ctx_t
224 openvas_init_gpgme_ctx (const gchar *subdir)
225 {
226  char *path;
227  gpgme_ctx_t ctx;
228 
229  path = determine_gpghome (subdir);
230  ctx = openvas_init_gpgme_ctx_from_dir (path);
231  g_free (path);
232  return ctx;
233 }
234 
235 void
236 set_gpghome (const char *path)
237 {
238  gpghome = g_strdup (path);
239 }
240 
250 static char *
251 get_sysconf_gpghome (void)
252 {
253  char *envdir = NULL;
254 
255  envdir = getenv ("OPENVAS_GPGHOME");
256  if (gpghome)
257  return g_strdup (gpghome);
258  else if (envdir)
259  return g_strdup (envdir);
260  else
261  return g_build_filename (OPENVAS_SYSCONF_DIR, "gnupg", NULL);
262 }
263 
276 gpgme_ctx_t
278 {
279  gpgme_ctx_t ctx;
280  char *path;
281 
282  path = get_sysconf_gpghome ();
283  ctx = openvas_init_gpgme_ctx_from_dir (path);
284  g_free (path);
285  return ctx;
286 }
gpgme_ctx_t openvas_init_gpgme_ctx(const gchar *subdir)
Returns a new gpgme context.
Definition: gpgme_util.c:224
#define err(x)
gpgme_ctx_t openvas_init_gpgme_sysconf_ctx(void)
Returns a new gpgme context using the sycconf directory.
Definition: gpgme_util.c:277
void set_gpghome(const char *path)
Definition: gpgme_util.c:236
#define G_LOG_DOMAIN
GLib log domain.
Definition: gpgme_util.c:47
gpgme_ctx_t openvas_init_gpgme_ctx_from_dir(const gchar *dir)
Returns a new gpgme context.
Definition: gpgme_util.c:102
Protos and data structures for GPGME utilities.