/* Draw frames WITH-OUT texturing one above other with blending */ void test5(struct globalStruct *globals) { timeval startTime, endTime; unsigned long diffTime2; int i; glEnable(GL_BLEND); glBlendEquation(GL_FUNC_ADD); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); float *pVertexArray, *pTexCoordArray; common_init_gl_vertices(globals->inNumberOfObjectsPerSide, &pVertexArray); common_init_gl_texcoords(globals->inNumberOfObjectsPerSide, &pTexCoordArray); gettimeofday(&startTime, NULL); for(i = 0;(i < globals->numTestIterations)&&(!globals->quitSignal);i ++) { SGXPERF_STARTPROFILEUNIT; glClear(GL_COLOR_BUFFER_BIT); common_gl_draw(globals, globals->inNumberOfObjectsPerSide); common_eglswapbuffers(globals, globals->eglDisplay, globals->eglSurface); SGXPERF_ENDPROFILEUNIT } gettimeofday(&endTime, NULL); diffTime2 = (tv_diff(&startTime, &endTime))/globals->numTestIterations; common_log(globals, 5, diffTime2); glDisableVertexAttribArray(VERTEX_ARRAY); glDisable(GL_BLEND); common_deinit_gl_vertices(pVertexArray); }
void _psOSCd_log(const char *fmt, va_list ap) { va_list ap2; va_copy(ap2, ap); common_log(LOG_INFO, fmt, ap2); }
static void server_socket_create_name (void) { if ((s_socket_dir = strdup (SOCKET_DIR_TEMPLATE)) == NULL) { common_log (LOG_FATAL, "strdup"); } if (mkdtemp (s_socket_dir) == NULL) { common_log (LOG_FATAL, "Cannot mkdtemp"); } if ((s_socket_name = (char *)malloc (strlen (s_socket_dir) + 100)) == NULL) { common_log (LOG_FATAL, "Cannot malloc"); } sprintf (s_socket_name, "%s/agent.S", s_socket_dir); }
void psOSCd_debug(const char *fmt, ...) { if (verbose()) { va_list ap; va_start(ap, fmt); common_log(LOG_INFO, fmt, ap); } }
static void server_socket_accept_terminate (pthread_t thread) { accept_command_t stop = ACCEPT_THREAD_STOP; if (write (s_fd_accept_terminate[1], &stop, sizeof (stop)) == -1) { common_log (LOG_FATAL, "write failed"); } pthread_join (thread, NULL); close (s_fd_accept_terminate[0]); close (s_fd_accept_terminate[1]); }
static void server_socket_accept (const int fd, pthread_t *thread, dconfig_data_t *config) { thread_list_t entry = malloc (sizeof (struct thread_list_s)); memset (entry, 0, sizeof (struct thread_list_s)); entry->fd = fd; entry->config = config; if (pthread_create (thread, NULL, _server_socket_accept, (void *)entry)) { common_log (LOG_FATAL, "pthread failed"); } }
static PKCS11H_BOOL pkcs11_pin_prompt_hook ( void * const global_data, void * const user_data, const pkcs11h_token_id_t token, const unsigned retry, char * const pin, const size_t max_pin ) { char cmd[1024]; assuan_context_t ctx = user_data; unsigned char *pin_read = NULL; size_t pin_len; int rc; int ret = FALSE; (void)global_data; snprintf ( cmd, sizeof(cmd), "NEEDPIN PIN required for token '%s' (try %u)", token->display, retry ); if ((rc = assuan_inquire (ctx, cmd, &pin_read, &pin_len, 1024))) { common_log (LOG_WARNING,"PIN inquire error: %d", rc); goto cleanup; } if (pin_len==0 || (pin_len+1 > max_pin)) { goto cleanup; } strcpy (pin, (char *)pin_read); ret = TRUE; cleanup: if (pin_read != NULL) { memset (pin_read, 0, strlen ((char *)pin_read)); free (pin_read); pin_read = NULL; } return ret; }
static void * _server_socket_command_handler (void *arg) { thread_list_t entry = (thread_list_t)arg; accept_command_t clean = ACCEPT_THREAD_CLEAN; command_handler (entry->fd, entry->config); entry->stopped = 1; if (write (s_fd_accept_terminate[1], &clean, sizeof (clean)) == -1) { common_log (LOG_FATAL, "write failed"); } return NULL; }
static PKCS11H_BOOL pkcs11_token_prompt_hook ( void * const global_data, void * const user_data, const pkcs11h_token_id_t token, const unsigned retry ) { char cmd[1024]; unsigned char *user_read = NULL; size_t user_read_len = 0; assuan_context_t ctx = user_data; int rc; int ret = FALSE; (void)global_data; (void)retry; snprintf ( cmd, sizeof(cmd), "NEEDPIN Please insert token '%s' !!!DO NOT ENTER PIN HERE!!!!", token->display ); if ((rc = assuan_inquire (ctx, cmd, &user_read, &user_read_len, 1024))) { common_log (LOG_WARNING, "Token inquire error: %d", rc); goto cleanup; } if (!strcmp ((char *)user_read, "cancel")) { goto cleanup; } ret = TRUE; cleanup: if (user_read != NULL) { memset (user_read, 0, strlen ((char *)user_read)); free (user_read); user_read = NULL; } return ret; }
static int server_socket_create (void) { struct sockaddr_un serv_addr; int fd = -1; int rc = -1; if ((rc = assuan_sock_init()) != 0) { common_log (LOG_ERROR,"Cannot init socket %s", gpg_strerror (rc)); goto cleanup; } memset (&serv_addr, 0, sizeof (serv_addr)); serv_addr.sun_family = AF_UNIX; assert (strlen (s_socket_name) + 1 < sizeof (serv_addr.sun_path)); strcpy (serv_addr.sun_path, s_socket_name); if ((fd = assuan_sock_new (AF_UNIX, SOCK_STREAM, 0)) == -1) { common_log (LOG_ERROR, "Cannot create socket", s_socket_name); goto cleanup; } if ((rc = assuan_sock_bind (fd, (struct sockaddr*)&serv_addr, sizeof (serv_addr))) == -1) { common_log (LOG_ERROR, "Cannot bing to socket '%s'", s_socket_name); goto cleanup; } if ((rc = listen (fd, SOMAXCONN)) == -1) { common_log (LOG_ERROR, "Cannot listen to socket '%s'", s_socket_name); goto cleanup; } rc = 0; cleanup: if (rc != 0) { server_socket_close (fd); common_log (LOG_FATAL, "Cannot handle socket"); } common_log (LOG_INFO, "Listening to socket '%s'", s_socket_name); return fd; }
/** Sign data (set by SETDATA) with certificate id in line. */ gpg_error_t cmd_pksign (assuan_context_t ctx, char *line) { static const unsigned char rmd160_prefix[] = /* (1.3.36.3.2.1) */ { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x24, 0x03, 0x02, 0x01, 0x05, 0x00, 0x04, 0x14 }; static const unsigned char md5_prefix[] = /* (1.2.840.113549.2.5) */ { 0x30, 0x2c, 0x30, 0x09, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10 }; static const unsigned char sha1_prefix[] = /* (1.3.14.3.2.26) */ { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14 }; static const unsigned char sha224_prefix[] = /* (2.16.840.1.101.3.4.2.4) */ { 0x30, 0x2D, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04, 0x05, 0x00, 0x04, 0x1C }; static const unsigned char sha256_prefix[] = /* (2.16.840.1.101.3.4.2.1) */ { 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20 }; static const unsigned char sha384_prefix[] = /* (2.16.840.1.101.3.4.2.2) */ { 0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05, 0x00, 0x04, 0x30 }; static const unsigned char sha512_prefix[] = /* (2.16.840.1.101.3.4.2.3) */ { 0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40 }; gpg_err_code_t error = GPG_ERR_GENERAL; pkcs11h_certificate_id_t cert_id = NULL; pkcs11h_certificate_t cert = NULL; cmd_data_t *data = (cmd_data_t *)assuan_get_pointer (ctx); cmd_data_t *_data = data; int need_free__data = 0; int session_locked = 0; unsigned char *sig = NULL; size_t sig_len; char hash[100] = ""; enum { INJECT_NONE, INJECT_RMD160, INJECT_MD5, INJECT_SHA1, INJECT_SHA224, INJECT_SHA256, INJECT_SHA384, INJECT_SHA512 } inject = INJECT_NONE; if (data->data == NULL) { error = GPG_ERR_INV_DATA; goto cleanup; } while (*line != '\x0' && (isspace (*line) || *line == '-')) { if (*line == '-') { static const char *hashprm = "--hash="; char *p = line; while (*line != '\x0' && !isspace (*line)) { line++; } line++; if (!strncmp (p, hashprm, strlen (hashprm))) { p += strlen (hashprm); *(line-1) = '\0'; snprintf (hash, sizeof(hash), "%s", p); } } else { line++; } } if (*line == '\x0') { error = GPG_ERR_INV_DATA; goto cleanup; } /* * sender prefixed data with algorithm OID */ if (strcmp(hash, "")) { if (!strcmp(hash, "rmd160") && data->size == (0x14 + sizeof(rmd160_prefix)) && !memcmp (data->data, rmd160_prefix, sizeof (rmd160_prefix))) { inject = INJECT_NONE; } else if (!strcmp(hash, "rmd160") && data->size == 0x14) { inject = INJECT_RMD160; } else if (!strcmp(hash, "md5") && data->size == (0x10 + sizeof(md5_prefix)) && !memcmp (data->data, md5_prefix, sizeof (md5_prefix))) { inject = INJECT_NONE; } else if (!strcmp(hash, "md5") && data->size == 0x10) { inject = INJECT_MD5; } else if (!strcmp(hash, "sha1") && data->size == (0x14 + sizeof(sha1_prefix)) && !memcmp (data->data, sha1_prefix, sizeof (sha1_prefix))) { inject = INJECT_NONE; } else if (!strcmp(hash, "sha1") && data->size == 0x14) { inject = INJECT_SHA1; } else if (!strcmp(hash, "sha224") && data->size == (0x1c + sizeof(sha224_prefix)) && !memcmp (data->data, sha224_prefix, sizeof (sha224_prefix))) { inject = INJECT_NONE; } else if (!strcmp(hash, "sha224") && data->size == 0x1c) { inject = INJECT_SHA224; } else if (!strcmp(hash, "sha256") && data->size == (0x20 + sizeof(sha256_prefix)) && !memcmp (data->data, sha256_prefix, sizeof (sha256_prefix))) { inject = INJECT_NONE; } else if (!strcmp(hash, "sha256") && data->size == 0x20) { inject = INJECT_SHA256; } else if (!strcmp(hash, "sha384") && data->size == (0x30 + sizeof(sha384_prefix)) && !memcmp (data->data, sha384_prefix, sizeof (sha384_prefix))) { inject = INJECT_NONE; } else if (!strcmp(hash, "sha384") && data->size == 0x30) { inject = INJECT_SHA384; } else if (!strcmp(hash, "sha512") && data->size == (0x40 + sizeof(sha512_prefix)) && !memcmp (data->data, sha512_prefix, sizeof (sha512_prefix))) { inject = INJECT_NONE; } else if (!strcmp(hash, "sha512") && data->size == 0x40) { inject = INJECT_SHA512; } else { common_log (LOG_DEBUG, "unsupported hash algo (hash=%s,size=%d)", hash, data->size); error = GPG_ERR_UNSUPPORTED_ALGORITHM; goto cleanup; } } else { if ( data->size == 0x10 + sizeof (md5_prefix) || data->size == 0x14 + sizeof (sha1_prefix) || data->size == 0x14 + sizeof (rmd160_prefix) ) { if ( memcmp (data->data, md5_prefix, sizeof (md5_prefix)) && memcmp (data->data, sha1_prefix, sizeof (sha1_prefix)) && memcmp (data->data, rmd160_prefix, sizeof (rmd160_prefix)) ) { error = GPG_ERR_UNSUPPORTED_ALGORITHM; goto cleanup; } } else { /* * unknown hash algorithm; * gnupg's scdaemon forces to SHA1 */ inject = INJECT_SHA1; } } if (inject != INJECT_NONE) { const unsigned char *oid; size_t oid_size; switch (inject) { case INJECT_RMD160: oid = rmd160_prefix; oid_size = sizeof (rmd160_prefix); break; case INJECT_MD5: oid = md5_prefix; oid_size = sizeof (md5_prefix); break; case INJECT_SHA1: oid = sha1_prefix; oid_size = sizeof (sha1_prefix); break; case INJECT_SHA224: oid = sha224_prefix; oid_size = sizeof (sha224_prefix); break; case INJECT_SHA256: oid = sha256_prefix; oid_size = sizeof(sha256_prefix); break; case INJECT_SHA384: oid = sha384_prefix; oid_size = sizeof(sha384_prefix); break; case INJECT_SHA512: oid = sha512_prefix; oid_size = sizeof(sha512_prefix); break; default: error = GPG_ERR_INV_DATA; goto cleanup; } need_free__data = 1; if ((_data = (cmd_data_t *)malloc (sizeof (cmd_data_t))) == NULL) { error = GPG_ERR_ENOMEM; goto cleanup; } if ((_data->data = (unsigned char *)malloc (data->size + oid_size)) == NULL) { error = GPG_ERR_ENOMEM; goto cleanup; } _data->size = 0; memmove (_data->data+_data->size, oid, oid_size); _data->size += oid_size; memmove (_data->data+_data->size, data->data, data->size); _data->size += data->size; } if ( (error = _get_certificate_by_name ( ctx, line, OPENPGP_SIGN, &cert_id, NULL )) != GPG_ERR_NO_ERROR ) { goto cleanup; } if ( (error = common_map_pkcs11_error ( pkcs11h_certificate_create ( cert_id, ctx, PKCS11H_PROMPT_MASK_ALLOW_ALL, PKCS11H_PIN_CACHE_INFINITE, &cert ) )) != GPG_ERR_NO_ERROR ) { goto cleanup; } if ( (error = common_map_pkcs11_error ( pkcs11h_certificate_lockSession (cert) )) != GPG_ERR_NO_ERROR ) { goto cleanup; } session_locked = 1; if ( (error = common_map_pkcs11_error ( pkcs11h_certificate_signAny ( cert, CKM_RSA_PKCS, _data->data, _data->size, NULL, &sig_len ) )) != GPG_ERR_NO_ERROR ) { goto cleanup; } if ((sig = (unsigned char *)malloc (sig_len)) == NULL) { error = GPG_ERR_ENOMEM; goto cleanup; } if ( (error = common_map_pkcs11_error ( pkcs11h_certificate_signAny ( cert, CKM_RSA_PKCS, _data->data, _data->size, sig, &sig_len ) )) != GPG_ERR_NO_ERROR || (error = assuan_send_data(ctx, sig, sig_len)) != GPG_ERR_NO_ERROR ) { goto cleanup; } error = GPG_ERR_NO_ERROR; cleanup: if (session_locked) { pkcs11h_certificate_releaseSession (cert); session_locked = 0; } if (cert != NULL) { pkcs11h_certificate_freeCertificate (cert); cert = NULL; } if (cert_id != NULL) { pkcs11h_certificate_freeCertificateId (cert_id); cert_id = NULL; } if (sig != NULL) { free (sig); sig = NULL; } if (need_free__data) { free (_data->data); _data->data = NULL; free (_data); _data = NULL; } return gpg_error (error); }
int main (int argc, char *argv[]) { enum { OPT_SERVER, OPT_MUTLI_SERVER, OPT_DAEMON, OPT_VERBOSE, OPT_QUIET, OPT_SH, OPT_CSH, OPT_OPTIONS, OPT_NO_DETACH, OPT_LOG_FILE, OPT_VERSION, OPT_HELP }; static struct option long_options[] = { { "server", no_argument, NULL, OPT_SERVER }, { "multi-server", no_argument, NULL, OPT_MUTLI_SERVER }, { "daemon", no_argument, NULL, OPT_DAEMON }, { "verbose", no_argument, NULL, OPT_VERBOSE }, { "quiet", no_argument, NULL, OPT_QUIET }, { "sh", no_argument, NULL, OPT_SH }, { "csh", no_argument, NULL, OPT_CSH }, { "options", required_argument, NULL, OPT_OPTIONS }, { "no-detach", no_argument, NULL, OPT_NO_DETACH }, { "log-file", required_argument, NULL, OPT_LOG_FILE }, { "version", no_argument, NULL, OPT_VERSION }, { "help", no_argument, NULL, OPT_HELP }, { NULL, 0, NULL, 0 } }; int long_options_ret; int base_argc = 1; int usage_ok = 1; enum { RUN_MODE_NONE, RUN_MODE_SERVER, RUN_MODE_MULTI_SERVER, RUN_MODE_DAEMON } run_mode = RUN_MODE_NONE; int env_is_csh = 0; int log_verbose = 0; int log_quiet = 0; int no_detach = 0; char *config_file = NULL; char *log_file = NULL; char *home_dir = NULL; int have_at_least_one_provider=0; FILE *fp_log = NULL; int i; CK_RV rv; dconfig_data_t config; const char * CONFIG_SUFFIX = ".conf"; char *default_config_file = NULL; #if !defined(HAVE_W32_SYSTEM) s_parent_pid = getpid (); #endif if ((default_config_file = (char *)malloc (strlen (PACKAGE)+strlen (CONFIG_SUFFIX)+1)) == NULL) { common_log (LOG_FATAL, "malloc failed"); } sprintf (default_config_file, "%s%s", PACKAGE, CONFIG_SUFFIX); common_set_log_stream (stderr); while ((long_options_ret = getopt_long (argc, argv, "vqsc", long_options, NULL)) != -1) { base_argc++; switch (long_options_ret) { case OPT_SERVER: run_mode = RUN_MODE_SERVER; break; case OPT_MUTLI_SERVER: run_mode = RUN_MODE_MULTI_SERVER; break; case OPT_DAEMON: run_mode = RUN_MODE_DAEMON; break; case OPT_VERBOSE: case 'v': log_verbose = 1; break; case OPT_QUIET: case 'q': log_quiet = 1; break; case OPT_SH: case 's': break; case OPT_CSH: case 'c': env_is_csh = 1; break; case OPT_OPTIONS: base_argc++; config_file = strdup (optarg); break; case OPT_NO_DETACH: no_detach = 1; break; case OPT_LOG_FILE: base_argc++; log_file = strdup (optarg); break; case OPT_VERSION: printf ( "%s %s\n" "\n" "Copyright (c) 2006-2007 Zeljko Vrba <*****@*****.**>\n" "Copyright (c) 2006-2011 Alon Bar-Lev <*****@*****.**>\n" "\n" "This is free software; see the source for copying conditions.\n" "There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n", PACKAGE, PACKAGE_VERSION ); exit (1); break; case OPT_HELP: usage_ok = 0; break; default: usage_ok = 0; break; } } if (base_argc < argc) { if (!strcmp (argv[base_argc], "--")) { base_argc++; } } if (!usage_ok) { usage (argv[0]); } if (run_mode == RUN_MODE_NONE) { common_log (LOG_FATAL, "please use the option `--daemon' to run the program in the background"); } #if defined(HAVE_W32_SYSTEM) if (run_mode == RUN_MODE_DAEMON) { common_log (LOG_FATAL, "daemon mode is not supported"); } #endif home_dir = get_home_dir (); if (config_file == NULL) { if ((config_file = (char *)malloc (strlen (home_dir) + strlen (default_config_file)+2)) == NULL) { common_log (LOG_FATAL, "malloc failed"); } sprintf (config_file, "%s%c%s", home_dir, CONFIG_PATH_SEPARATOR, default_config_file); } if ( !dconfig_read (config_file, &config) && !dconfig_read (CONFIG_SYSTEM_CONFIG, &config) ) { common_log (LOG_FATAL, "Cannot open configuration file"); } if (log_file != NULL) { if (config.log_file != NULL) { free (config.log_file); } if ((config.log_file = strdup (log_file)) == NULL) { common_log (LOG_FATAL, "strdup failed"); } } if (log_verbose) { config.verbose = 1; } #if !defined(HAVE_W32_SYSTEM) signal (SIGPIPE, SIG_IGN); signal (SIGINT, on_signal); signal (SIGTERM, on_signal); signal (SIGABRT, on_signal); signal (SIGHUP, on_signal); #endif if (log_file != NULL) { if (strcmp (log_file, "stderr")) { if ((fp_log = fopen (log_file, "a")) != NULL) { common_set_log_stream (fp_log); } } } else if (config.log_file != NULL) { if (strcmp (config.log_file, "stderr")) { if ((fp_log = fopen (config.log_file, "a")) != NULL) { common_set_log_stream (fp_log); } } } if (config.debug) { common_log (LOG_DEBUG, "version: %s", PACKAGE_VERSION); dconfig_print (&config); common_log (LOG_DEBUG, "run_mode: %d", run_mode); common_log (LOG_DEBUG, "crypto: %s", #if defined(ENABLE_OPENSSL) "openssl" #elif defined(ENABLE_GNUTLS) "gnutls" #else "invalid" #endif ); } #if !defined(HAVE_W32_SYSTEM) if (run_mode == RUN_MODE_DAEMON || run_mode == RUN_MODE_MULTI_SERVER) { server_socket_create_name (); } /* * fork before doing PKCS#11 stuff * some providers don't behave well */ if (run_mode == RUN_MODE_DAEMON) { pid_t pid; pid = fork (); if (pid == -1) { common_log (LOG_FATAL, "fork failed"); } if (pid != 0) { static const char *key = "SCDAEMON_INFO"; char env[1024]; snprintf (env, sizeof (env), "%s:%lu:1", s_socket_name, (unsigned long)pid); if (argc - base_argc > 0) { setenv(key, env, 1); execvp (argv[base_argc], &(argv[base_argc])); kill (pid, SIGTERM); exit (1); } else { if (env_is_csh) { *strchr (env, '=') = ' '; printf ("setenv %s %s\n", key, env); } else { printf ("%s=%s; export %s\n", key, env, key); } exit (0); } } if (!no_detach) { int i; for (i=0;i<3;i++) { if (fileno (common_get_log_stream ()) != i) { close (i); } } if (setsid () == -1) { common_log (LOG_FATAL, "setsid failed"); } } if (chdir ("/") == -1) { common_log (LOG_FATAL, "chdir failed"); } if (argc - base_argc > 0) { struct sigaction sa; memset (&sa, 0, sizeof (sa)); sigemptyset (&sa.sa_mask); #if defined(SA_INTERRUPT) sa.sa_flags |= SA_INTERRUPT; #endif sa.sa_handler = on_alarm; sigaction (SIGALRM, &sa, NULL); alarm (10); } } #endif /* HAVE_W32_SYSTEM */ assuan_set_assuan_log_prefix (PACKAGE); assuan_set_assuan_log_stream (common_get_log_stream ()); #if defined(USE_GNUTLS) if (gnutls_global_init () != GNUTLS_E_SUCCESS) { common_log (LOG_FATAL, "Cannot initialize gnutls"); } #endif if ((rv = pkcs11h_initialize ()) != CKR_OK) { common_log (LOG_FATAL, "Cannot initialize PKCS#11: %s", pkcs11h_getMessage (rv)); } pkcs11h_setLogLevel (config.verbose ? PKCS11H_LOG_DEBUG2 : PKCS11H_LOG_INFO); pkcs11h_setLogHook (pkcs11_log_hook, NULL); pkcs11h_setTokenPromptHook (pkcs11_token_prompt_hook, NULL); pkcs11h_setPINPromptHook (pkcs11_pin_prompt_hook, NULL); pkcs11h_setProtectedAuthentication (TRUE); for (i=0;i<DCONFIG_MAX_PROVIDERS;i++) { if ( config.providers[i].name != NULL && config.providers[i].library != NULL ) { if ( (rv = pkcs11h_addProvider ( config.providers[i].name, config.providers[i].library, config.providers[i].allow_protected, config.providers[i].private_mask, PKCS11H_SLOTEVENT_METHOD_POLL, 0, config.providers[i].cert_is_private )) != CKR_OK ) { common_log (LOG_WARNING, "Cannot add PKCS#11 provider '%s': %ld-'%s'", config.providers[i].name, rv, pkcs11h_getMessage (rv)); } else { have_at_least_one_provider = 1; } } } if (!have_at_least_one_provider) { common_log (LOG_FATAL, "Could not load any provider"); } #if defined(HAVE_W32_SYSTEM) command_handler (-1, &config); #else { pthread_t accept_thread = 0; int accept_socket = -1; if (run_mode == RUN_MODE_DAEMON || run_mode == RUN_MODE_MULTI_SERVER) { accept_socket = server_socket_create (); server_socket_accept (accept_socket, &accept_thread, &config); } if (run_mode == RUN_MODE_DAEMON) { /* * Emulate assuan behavior */ int fds[2]; char c; if (pipe (fds)==-1) { common_log (LOG_FATAL, "Could not create pipe"); } close (0); dup2 (fds[0], 0); close (fds[0]); while (read (0, &c, 1) == -1 && errno == EINTR); close (fds[1]); } else { command_handler (-1, &config); } if (run_mode == RUN_MODE_DAEMON || run_mode == RUN_MODE_MULTI_SERVER) { server_socket_accept_terminate (accept_thread); server_socket_close (accept_socket); } } #endif pkcs11h_terminate (); #if defined(USE_GNUTLS) gnutls_global_deinit (); #endif dconfig_free (&config); if (log_file != NULL) { free (log_file); log_file = NULL; } if (config_file != NULL) { free (config_file); config_file = NULL; } if (default_config_file != NULL) { free (default_config_file); default_config_file = NULL; } if (home_dir != NULL) { free (home_dir); home_dir = NULL; } if (fp_log != NULL) { fclose (fp_log); fp_log = NULL; } return 0; }
static char *get_home_dir (void) { #if defined(HAVE_W32_SYSTEM) static const char * GPG_HOME_KEY = "Software\\GNU\\GnuPG"; const char *HOME_ENV = getenv ("USERPROFILE"); #else const char *HOME_ENV = getenv ("HOME"); #endif char *home_dir = NULL; if (home_dir == NULL && getenv ("GNUPGHOME") != NULL) { home_dir=strdup (getenv ("GNUPGHOME")); } #if defined(HAVE_W32_SYSTEM) if (home_dir == NULL) { char key_val[1024]; HKEY hkey = NULL; DWORD dw = 0; if (RegOpenKeyEx (HKEY_CURRENT_USER, GPG_HOME_KEY, 0, KEY_READ, &hkey) != ERROR_SUCCESS) { if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, GPG_HOME_KEY, 0, KEY_READ, &hkey) != ERROR_SUCCESS) { hkey = NULL; } } if (hkey != NULL) { if ( RegQueryValueEx ( hkey, "HomeDir", NULL, NULL, (PBYTE)key_val, &dw ) == ERROR_SUCCESS ) { home_dir = strdup (key_val); } } if (hkey != NULL) { RegCloseKey (hkey); } } #endif if (home_dir == NULL) { if ( CONFIG_GPG_HOME[0] == '~' && HOME_ENV != NULL ) { if ((home_dir=(char *)malloc (strlen (CONFIG_GPG_HOME) + strlen (HOME_ENV))) == NULL) { common_log (LOG_FATAL, "malloc failed"); } sprintf (home_dir, "%s%s", HOME_ENV, CONFIG_GPG_HOME+1); } else { home_dir = strdup (CONFIG_GPG_HOME); } } return home_dir; }
static void * _server_socket_accept (void *arg) { thread_list_t _entry = (thread_list_t)arg; dconfig_data_t *config = _entry->config; int fd = _entry->fd; thread_list_t thread_list_head = NULL; int rc = 0; free (_entry); _entry = NULL; if (pipe (s_fd_accept_terminate) == -1) { common_log (LOG_FATAL, "pipe failed"); } while (rc != -1) { fd_set fdset; FD_ZERO (&fdset); FD_SET (s_fd_accept_terminate[0], &fdset); FD_SET (fd, &fdset); rc = select (FD_SETSIZE, &fdset, NULL, NULL, NULL); if (rc != -1 && rc != 0) { if (FD_ISSET (s_fd_accept_terminate[0], &fdset)) { accept_command_t cmd; if ( (rc = read ( s_fd_accept_terminate[0], &cmd, sizeof (cmd)) ) == sizeof (cmd) ) { if (cmd == ACCEPT_THREAD_STOP) { rc = -1; } else if (cmd == ACCEPT_THREAD_CLEAN) { thread_list_t entry = thread_list_head; thread_list_t prev = NULL; common_log (LOG_DEBUG, "Cleaning up closed thread"); while (entry != NULL) { if (entry->stopped) { thread_list_t temp = entry; common_log (LOG_DEBUG, "Cleaning up closed thread1"); pthread_join (entry->thread, NULL); close (entry->fd); if (prev == NULL) { thread_list_head = entry->next; } else { prev->next = entry->next; } entry = entry->next; free (temp); } else { prev = entry; entry = entry->next; } } } } } else if (FD_ISSET (fd, &fdset)) { struct sockaddr_un addr; socklen_t addrlen = sizeof (addr); int fd2; if ((rc = fd2 = accept (fd, (struct sockaddr *)&addr, &addrlen)) != -1) { thread_list_t entry = NULL; common_log (LOG_DEBUG, "Accepted new socket connection"); if ((entry = (thread_list_t)malloc (sizeof (struct thread_list_s))) == NULL) { common_log (LOG_FATAL, "malloc failed"); } memset (entry, 0, sizeof (struct thread_list_s)); entry->next = thread_list_head; entry->fd = fd2; entry->config = config; thread_list_head = entry; if ( pthread_create ( &entry->thread, NULL, _server_socket_command_handler, entry ) ) { common_log (LOG_FATAL, "pthread failed"); } } } } } common_log (LOG_DEBUG, "Cleaning up threads"); while (thread_list_head != NULL) { thread_list_t entry = thread_list_head; thread_list_head = thread_list_head->next; common_log (LOG_DEBUG, "Cleaning up thread1"); close (entry->fd); pthread_join (entry->thread, NULL); free (entry); } return NULL; }
/** Command handler (single-threaded). If fd == -1, this is a pipe server, otherwise fd is UNIX socket fd to which client connected. */ static void command_handler (const int fd, dconfig_data_t *config) { assuan_context_t ctx = NULL; cmd_data_t data; int ret; memset (&data, 0, sizeof (data)); data.config = config; if ((ret = assuan_new(&ctx)) != 0) { common_log (LOG_ERROR,"failed to create assuan context %s", gpg_strerror (ret)); goto cleanup; } if(fd < 0) { assuan_fd_t fds[2] = {assuan_fdopen(0), assuan_fdopen(1)}; ret = assuan_init_pipe_server (ctx, fds); } else { ret = assuan_init_socket_server (ctx, INT2FD(fd), ASSUAN_SOCKET_SERVER_ACCEPTED); } if (ret != 0) { common_log (LOG_ERROR,"failed to initialize server: %s", gpg_strerror (ret)); goto cleanup; } if(((ret = register_commands(ctx))) != 0) { common_log (LOG_ERROR,"failed to register assuan commands: %s", gpg_strerror (ret)); goto cleanup; } if (config->verbose) { assuan_set_log_stream (ctx, common_get_log_stream()); } assuan_set_pointer (ctx, &data); while (1) { if ((ret = assuan_accept (ctx)) == -1) { break; } if (ret != 0) { common_log (LOG_WARNING,"assuan_accept failed: %s", gpg_strerror(ret)); break; } if ((ret = assuan_process (ctx)) != 0) { common_log (LOG_WARNING,"assuan_process failed: %s", gpg_strerror(ret)); } } cleanup: if (ctx != NULL) { cmd_free_data (ctx); assuan_release (ctx); ctx = NULL; } }