/* Start the pinentry event loop. The program will start to process Assuan commands until it is finished or an error occurs. If an error occurs, -1 is returned. Otherwise, 0 is returned. */ int pinentry_loop (void) { fcntl(STDIN_FILENO, 73); // Disable SIGPIPE fcntl(STDOUT_FILENO, 73); // Disable SIGPIPE return pinentry_loop2 (STDIN_FILENO, STDOUT_FILENO); }
int main (int argc, char **argv) { #ifndef HAVE_W32CE_SYSTEM void *handle; #endif w32_infd = STDIN_FILENO; w32_outfd = STDOUT_FILENO; #ifdef HAVE_W32CE_SYSTEM parse_std_file_handles (&argc, &argv); #endif pinentry_init (PGMNAME); /* Consumes all arguments. */ if (pinentry_parse_opts (argc, argv)) exit (EXIT_SUCCESS); /* debugfp = fopen ("pinentry.log", "w"); */ /* if (!debugfp) */ /* debugfp = stderr; */ /* We need to load a function because that one is only available since W2000 but not in older NTs. */ #ifndef HAVE_W32CE_SYSTEM handle = LoadLibrary ("user32.dll"); if (handle) { void *foo; foo = GetProcAddress (handle, "LockSetForegroundWindow"); if (foo) lock_set_foreground_window = foo; else CloseHandle (handle); } #endif if (pinentry_loop2 (w32_infd, w32_outfd)) return 1; #ifdef HAVE_W32CE_SYSTEM Sleep (400); #endif return 0; }
JNIEXPORT void JNICALL Java_info_guardianproject_gpg_pinentry_PinentryDialog_connectToGpgAgent ( JNIEnv * env, jobject self, jint app_uid ) { int in, out, sock; _ctx.env = env; pe_activity_init(&_ctx, self); pe_get_internal_gnupghome(&_ctx); sock = connect_helper( app_uid ); if( sock < 0 ) { LOGE("connectToGpgAgent aborting"); return; } /* * we make sure we've connected to the correct server by checking that the * app_uid we passed (from our starting Intent) is the same uid of our peer. * This should always succeed, and doesn't provide any assurance we're NOT * connected to a malicious pinentry, but we check it because we can. * If it does fail, something incredibly janky is going on */ struct ucred credentials; int ucred_length = sizeof( struct ucred ); if( getsockopt( sock, SOL_SOCKET, SO_PEERCRED, &credentials, &ucred_length ) ) { LOGE("connectToGpgAgent: couldn't obtain peer's credentials"); close( sock ); return; } if( app_uid != credentials.uid ) { LOGE( "connectToGpgAgent: authentication error. Something JANKY is going on!" ); LOGE( " expected uid %d, but found %d", app_uid, credentials.uid ); close( sock ); return; } /* * fetch the stdin and stdout from the helper * over the socket so that we can * directly communicate with gpg-agent */ in = recv_fd ( sock ); if ( in == -1 ) { LOGE ( "STDIN receiving failed!\n" ); } out = recv_fd ( sock ); if ( out == -1 ) { LOGE ( "STDOUT receiving failed!\n" ); } /* * now we can act like a normal pinentry */ pinentry_init ( "pinentry-android" ); /* Consumes all arguments. */ if ( pinentry_parse_opts ( 0, 0 ) ) write ( sock, EXIT_SUCCESS, 1 ); // this only exits when done pinentry_loop2 ( in, out ); LOGD("pinentry_loop2 returned"); /* * the helper proces has stayed alive waiting for us * to finish, so here we send back the exit code */ int buf[1] = { EXIT_SUCCESS }; int r = write ( sock, buf, 1 ); if ( r < 0 ) LOGE ( "closing pinentry helper failed:" ); close( sock ); }