blob: 5e6762cb83bd3dc25ca6aa68377c20d743a81fc4 [file] [log] [blame]
/*
* nss - glue to NSS certificate database
*
* This file initially created by Google, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <errno.h>
#include <inttypes.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#define CONNMAN_API_SUBJECT_TO_CHANGE
#include <connman/plugin.h>
#include <connman/log.h>
#include <glib.h>
static const char *basename = "/tmp/nss-cert.";
static char *nss_get_certfile(const char *nickname, const uint8_t *id,
size_t id_len, gboolean is_pem)
{
char *argv[] = { SCRIPTDIR "/nss-get-cert",
NULL,
NULL,
NULL,
NULL};
int i, off, status;
GError *error;
char *filename;
int cert_filename_length;
char *mutable_nickname;
char mutable_pem_arg[] = "pem";
char mutable_der_arg[] = "der";
cert_filename_length = strlen(basename) + 2 * id_len + 1;
filename = g_malloc(cert_filename_length);
strcpy(filename, basename);
off = strlen(filename);
for (i = 0; i < id_len; i++, off += 2)
snprintf(&filename[off], 3, "%02x", id[i]);
filename[cert_filename_length - 1] = '\0';
mutable_nickname = g_strdup(nickname);
argv[1] = mutable_nickname;
argv[2] = is_pem ? mutable_pem_arg : mutable_der_arg;
argv[3] = filename;
if (!g_spawn_sync(
NULL, /* working directory */
argv,
NULL, /* envp */
0, /* flags */
NULL, /* child setup */
NULL, /* child setup user data */
NULL, /* child stdout */
NULL, /* child stderr */
&status, /* child exit status */
&error)) {
connman_error("g_spawn_async() failure: %s",
error->message);
g_error_free(error);
g_free(filename);
g_free(mutable_nickname);
return NULL;
}
g_free(mutable_nickname);
mutable_nickname = NULL;
if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
g_free(filename);
return NULL;
}
return filename;
}
char *nss_get_pem_certfile(const char *nickname, const uint8_t *id,
size_t id_len) {
return nss_get_certfile(nickname, id, id_len, TRUE);
}
char *nss_get_der_certfile(const char *nickname, const uint8_t *id,
size_t id_len) {
return nss_get_certfile(nickname, id, id_len, FALSE);
}
static int nss_init(void)
{
return 0;
}
static void nss_exit(void)
{
return;
}
CONNMAN_PLUGIN_DEFINE(nss, "NSS certificate glue", VERSION,
CONNMAN_PLUGIN_PRIORITY_DEFAULT, nss_init, nss_exit)