Ejemplo n.º 1
0
static gpgme_error_t
gpgsm_cancel(void *engine)
{
    engine_gpgsm_t gpgsm = engine;

    if(!gpgsm)
        return gpg_error(GPG_ERR_INV_VALUE);

    if(gpgsm->status_cb.fd != -1)
        _gpgme_io_close(gpgsm->status_cb.fd);
    if(gpgsm->input_cb.fd != -1)
        _gpgme_io_close(gpgsm->input_cb.fd);
    if(gpgsm->output_cb.fd != -1)
        _gpgme_io_close(gpgsm->output_cb.fd);
    if(gpgsm->message_cb.fd != -1)
        _gpgme_io_close(gpgsm->message_cb.fd);

    if(gpgsm->assuan_ctx)
    {
        assuan_disconnect(gpgsm->assuan_ctx);
        gpgsm->assuan_ctx = NULL;
    }

    return 0;
}
Ejemplo n.º 2
0
int ask_user_auth()
{
  int r;
  const char *argv[3];
  const char *pgmname = PIN_ENTRY; 
  ASSUAN_CONTEXT ctx;
  gchar buf[500];
  gsize buflen = sizeof(buf);
  gchar *buf_conv_ptr = NULL;
  const char *local_charset, *default_charset;
  gsize bytes_read=0, bytes_written=0;  
  gboolean is_utf8;

  memset(buf, 0, buflen);
  default_charset = setlocale(LC_CTYPE, "");

  setlocale(LC_ALL, "");
  bindtextdomain(PACKAGE, "/usr/share/locale");
  textdomain(PACKAGE);

  argv[0] = pgmname;
  argv[1] = NULL;
	
  r = assuan_pipe_connect(&ctx, pgmname, (char **) argv, 0);
  if (r) {
    printf(i18n("Can't connect to the PIN entry module: %s\n"),
	   assuan_strerror((AssuanError) r));
    goto err;
  }
	
  sprintf(buf, i18n("SETDESC Está a punto de realizar una firma electrónica con su clave de FIRMA del DNI electrónico. ¿Desea permitir esta operación?"));
  
  is_utf8 = g_get_charset(&local_charset);  
  buf_conv_ptr = g_convert_with_fallback(buf, buflen, local_charset, "UTF-8", 
					 NULL, &bytes_read, &bytes_written, NULL);
  if(!buf_conv_ptr) {
    printf(i18n("Error converting string to locale charset.\n"));
    goto err;
  }

  r = assuan_transact(ctx, buf_conv_ptr, NULL, NULL, NULL, NULL, NULL, NULL);
  if (r) {
    printf("SETDESC: %s\n", assuan_strerror((AssuanError) r));
    goto err;
  }
  while (1) {
    r = assuan_transact(ctx, "CONFIRM", NULL, NULL, NULL, NULL, NULL, NULL);
    if (r == ASSUAN_Canceled) {
      assuan_disconnect(ctx);
      return -2;
    }
    if (r) {
      printf("SETERROR: %s\n", assuan_strerror((AssuanError) r));
      goto err;
    }
    if (r == 0)
      break;
  }

  assuan_disconnect(ctx);	
  return 0;
 err:	
  assuan_disconnect(ctx);
  return -1;
}
Ejemplo n.º 3
0
int ask_and_verify_pin_code(struct sc_pkcs15_card *p15card,
			    struct sc_pkcs15_object *pin)
{
	int r;
	size_t len;
	const char *argv[3];
	const char *pgmname = PIN_ENTRY;
	ASSUAN_CONTEXT ctx;
	char buf[500];
	char errtext[100];
	struct entry_parm_s parm;
	struct sc_pkcs15_pin_info *pinfo = (struct sc_pkcs15_pin_info *) pin->data;
	
	argv[0] = pgmname;
	argv[1] = NULL;
	
	r = assuan_pipe_connect(&ctx, pgmname, (char **) argv, NULL);
	if (r) {
		printf("Can't connect to the PIN entry module: %s\n",
		       assuan_strerror((AssuanError) r));
		goto err;
	}
	sprintf(buf, "SETDESC Enter PIN [%s] for digital signing  ", pin->label);
	r = assuan_transact(ctx, buf, NULL, NULL, NULL, NULL, NULL, NULL);
	if (r) {
		printf("SETDESC: %s\n", assuan_strerror((AssuanError) r));
		goto err;
	}
	errtext[0] = 0;
	while (1) {
		if (errtext[0]) {
			sprintf(buf, "SETERROR %s", errtext);
			r = assuan_transact(ctx, buf, NULL, NULL, NULL, NULL, NULL, NULL);
			errtext[0] = 0;
		}
		parm.lines = 0;
		parm.size = sizeof(buf);
		parm.buffer = buf;
		r = assuan_transact(ctx, "GETPIN", getpin_cb, &parm, NULL, NULL, NULL, NULL);
		if (r == ASSUAN_Canceled) {
			assuan_disconnect(ctx);
			return -2;
		}
		if (r) {
			printf("GETPIN: %s\n", assuan_strerror((AssuanError) r));
			goto err;
		}
		len = strlen(buf);
		if (len < pinfo->min_length) {
			sprintf(errtext, "PIN code too short, min. %lu digits", (unsigned long) pinfo->min_length);
			continue;
		}
		if (len > pinfo->max_length) {
			sprintf(errtext, "PIN code too long, max. %lu digits", (unsigned long) pinfo->max_length);
			continue;
		}
		r = sc_pkcs15_verify_pin(p15card, pinfo, (const u8 *) buf, strlen(buf));
		switch (r) {
		case SC_ERROR_PIN_CODE_INCORRECT:
			sprintf(errtext, "PIN code incorrect (%d %s left)",
			       pinfo->tries_left, pinfo->tries_left == 1 ?
			       "try" : "tries");
			break;
		case 0:
			break;
		default:
			goto err;
		}
		if (r == 0)
			break;
	}

	assuan_disconnect(ctx);	
	return 0;
err:	
	assuan_disconnect(ctx);
	return -1;
}
Ejemplo n.º 4
0
/* Make a connection to the Unix domain socket NAME and return a new
   Assuan context in CTX.  SERVER_PID is currently not used but may
   become handy in the future.  With flags set to 1 sendmsg and
   recvmesg are used. */
assuan_error_t
assuan_socket_connect_ext(assuan_context_t *r_ctx,
                          const char *name, pid_t server_pid,
                          unsigned int flags)
{
    static struct assuan_io io = { _assuan_simple_read,
               _assuan_simple_write
    };

    assuan_error_t err;
    assuan_context_t ctx;
    int fd;
    struct sockaddr_un srvr_addr;
    size_t len;
    const char *s;

    if(!r_ctx || !name)
        return _assuan_error(ASSUAN_Invalid_Value);
    *r_ctx = NULL;

    /* We require that the name starts with a slash, so that we
       eventually can reuse this function for other socket types.  To
       make things easier we allow an optional dirver prefix.  */
    s = name;
    if(*s && s[1] == ':')
        s += 2;
    if(*s != DIRSEP_C && *s != '/')
        return _assuan_error(ASSUAN_Invalid_Value);

    if(strlen(name) + 1 >= sizeof srvr_addr.sun_path)
        return _assuan_error(ASSUAN_Invalid_Value);

    err = _assuan_new_context(&ctx);
    if(err)
        return err;
    ctx->deinit_handler = ((flags & 1)) ? _assuan_uds_deinit :  do_deinit;
    ctx->finish_handler = do_finish;

    fd = _assuan_sock_new(PF_LOCAL, SOCK_STREAM, 0);
    if(fd == -1)
    {
        _assuan_log_printf("can't create socket: %s\n", strerror(errno));
        _assuan_release_context(ctx);
        return _assuan_error(ASSUAN_General_Error);
    }

    memset(&srvr_addr, 0, sizeof srvr_addr);
    srvr_addr.sun_family = AF_LOCAL;
    strncpy(srvr_addr.sun_path, name, sizeof(srvr_addr.sun_path) - 1);
    srvr_addr.sun_path[sizeof(srvr_addr.sun_path) - 1] = 0;
    len = SUN_LEN(&srvr_addr);


    if(_assuan_sock_connect(fd, (struct sockaddr *) &srvr_addr, len) == -1)
    {
        _assuan_log_printf("can't connect to `%s': %s\n",
                           name, strerror(errno));
        _assuan_release_context(ctx);
        _assuan_close(fd);
        return _assuan_error(ASSUAN_Connect_Failed);
    }

    ctx->inbound.fd = fd;
    ctx->outbound.fd = fd;
    ctx->io = &io;
    if((flags & 1))
        _assuan_init_uds_io(ctx);

    /* initial handshake */
    {
        int okay, off;

        err = _assuan_read_from_server(ctx, &okay, &off);
        if(err)
            _assuan_log_printf("can't connect to server: %s\n",
                               assuan_strerror(err));
        else if(okay != 1)
        {
            /*LOG ("can't connect to server: `");*/
            _assuan_log_sanitized_string(ctx->inbound.line);
            fprintf(assuan_get_assuan_log_stream(), "'\n");
            err = _assuan_error(ASSUAN_Connect_Failed);
        }
    }

    if(err)
    {
        assuan_disconnect(ctx);
    }
    else
        *r_ctx = ctx;
    return 0;
}
Ejemplo n.º 5
0
int ask_user_consent(sc_card_t *card) {
    int res;
    struct stat buf;
    const char *argv[3];
    assuan_fd_t noclosefds[2];
    assuan_context_t ctx; 
    if ( (card==NULL) || (card->ctx==NULL)) return SC_ERROR_INVALID_ARGUMENTS;
    get_user_consent_env(card->ctx);
    res=stat(user_consent_app,&buf);
    if (res!=0) {
      /* TODO: check that pinentry file is executable */
      sc_debug(card->ctx,SC_LOG_DEBUG_NORMAL,"Invalid pinentry application: %s\n",user_consent_app);
      SC_FUNC_RETURN(card->ctx,SC_LOG_DEBUG_NORMAL,SC_ERROR_INVALID_ARGUMENTS);
    }
    argv[0]=user_consent_app;
    argv[1]=NULL;
    argv[2]=NULL;
    noclosefds[0]= fileno(stderr);
    noclosefds[1]= ASSUAN_INVALID_FD;
#ifdef HAVE_ASSUAN_2
    res = assuan_new(&ctx);
    if (res!=0) {
      sc_debug(card->ctx,SC_LOG_DEBUG_NORMAL,"Can't create the User Consent environment: %s\n",_gpg_error(res));
      SC_FUNC_RETURN(card->ctx,SC_LOG_DEBUG_NORMAL,SC_ERROR_INVALID_ARGUMENTS);
    }
    res = assuan_pipe_connect(ctx,user_consent_app,argv,noclosefds,NULL,NULL,0);
#else 
    res = assuan_pipe_connect(&ctx,user_consent_app,argv,0);
#endif
    if (res!=0) {
        sc_debug(card->ctx,SC_LOG_DEBUG_NORMAL,"Can't connect to the User Consent module: %s\n",_gpg_error(res));
        res=SC_ERROR_INVALID_ARGUMENTS; /* invalid or not available pinentry */
        goto exit;
    }
    res = assuan_transact(
       ctx, 
       "SETDESC Está a punto de realizar una firma electrónica con su clave de FIRMA del DNI electrónico.¿Desea permitir esta operación?", 
       NULL, NULL, NULL, NULL, NULL, NULL);
    if (res!=0) {
       sc_debug(card->ctx,SC_LOG_DEBUG_NORMAL,"SETDESC: %s\n", _gpg_error(res));
       res=SC_ERROR_CARD_CMD_FAILED; /* perhaps should use a better errcode */
       goto exit;
    }
    res = assuan_transact(ctx,"CONFIRM",NULL,NULL,NULL,NULL,NULL,NULL);
#ifdef HAVE_ASSUAN_1
    if (res == ASSUAN_Canceled) {
       sc_debug(card->ctx,SC_LOG_DEBUG_VERBOSE,"Sign cancelled by user");
       res= SC_ERROR_NOT_ALLOWED;
       goto exit;
    }
#endif
    if (res) {
       sc_debug(card->ctx,SC_LOG_DEBUG_NORMAL,"SETERROR: %s\n",_gpg_error(res));
       res=SC_ERROR_SECURITY_STATUS_NOT_SATISFIED;
     } else {
       res=SC_SUCCESS;
     }
exit:
#ifdef HAVE_ASSUAN_2
    assuan_release(ctx);
#else
    assuan_disconnect(ctx);
#endif
    SC_FUNC_RETURN(card->ctx,SC_LOG_DEBUG_NORMAL,res);
}