| /* |
| * 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) |