ff297c22a9ce51deeaf223d00a62738700e5d0d0
[pinentry.git] / kpinentry / pinentrycontroller.cpp
1 #include "pinentrycontroller.h"
2 #include "pinentrydialog.h"
3 #include "memory.h"
4 #include <kmessagebox.h>
5
6 PinEntryController::PinEntryController() : _pinentry( 0 )
7 {
8   int fds[2];
9   fds[0] = 0;
10   fds[1] = 1;
11   
12   assuan_set_malloc_hooks( secmem_malloc, secmem_realloc, secmem_free );
13   int rc = assuan_init_pipe_server( &_ctx, fds );
14   if( rc ) {
15     qDebug(assuan_strerror( static_cast<AssuanError>(rc) ));
16     exit(-1);
17   }
18   rc = registerCommands();
19
20   assuan_set_pointer( _ctx, this );
21 }
22
23 PinEntryController::~PinEntryController()
24 {
25   assuan_deinit_pipe_server( _ctx );
26 }
27
28 void PinEntryController::exec()
29 {
30   while( true ) {
31     int rc = assuan_accept( _ctx );
32     if( rc == -1 ) {
33       qDebug("Assuan terminated");
34       break;
35     } else if( rc ) {
36       qDebug("Assuan accept problem: %s", assuan_strerror( static_cast<AssuanError>(rc) ) );
37       break;
38     }
39     rc = assuan_process( _ctx );
40     if( rc ) {
41       qDebug("Assuan processing failed: %s", assuan_strerror( static_cast<AssuanError>(rc) ) );
42       continue;
43     }
44   }
45 }
46
47 int PinEntryController::registerCommands()
48 {
49   static struct {
50     const char *name;
51     int cmd_id;
52     int (*handler)(ASSUAN_CONTEXT, char *line);
53   } table[] = {
54     { "SETDESC",      0,  PinEntryController::assuanDesc },
55     { "SETPROMPT",    0,  PinEntryController::assuanPrompt },
56     { "SETERROR",     0,  PinEntryController::assuanError },
57     { "GETPIN",       0,  PinEntryController::assuanGetpin },
58     { "CONFIRM",      0,  PinEntryController::assuanConfirm },
59     { 0,0,0 }
60   };
61   int i, j, rc;
62   
63   for (i=j=0; table[i].name; i++) {
64     rc = assuan_register_command (_ctx,
65                                   table[i].cmd_id? table[i].cmd_id
66                                   : (ASSUAN_CMD_USER + j++),
67                                   table[i].name, table[i].handler);
68     if (rc) return rc;
69   }
70   return 0;
71 }
72
73 int PinEntryController::assuanDesc( ASSUAN_CONTEXT ctx, char* line )
74 {
75   //qDebug("PinEntryController::assuanDesc( %s )", line );
76   PinEntryController* that =   static_cast<PinEntryController*>(assuan_get_pointer(ctx));
77   that->_desc = QString::fromUtf8(line);
78   that->_error = QString::null;
79   return 0;
80 }
81
82 int PinEntryController::assuanPrompt( ASSUAN_CONTEXT ctx, char* line )
83 {
84   //qDebug("PinEntryController::assuanPrompt( %s )", line );
85   PinEntryController* that =   static_cast<PinEntryController*>(assuan_get_pointer(ctx));
86   that->_prompt = QString::fromUtf8(line);
87   that->_error = QString::null;
88   return 0;
89 }
90
91 int PinEntryController::assuanError( ASSUAN_CONTEXT ctx, char* line )
92 {
93   //qDebug("PinEntryController::assuanError( %s )", line );
94   PinEntryController* that =   static_cast<PinEntryController*>(assuan_get_pointer(ctx));
95   that->_error = QString::fromUtf8(line);
96   return 0;
97 }
98
99 int PinEntryController::assuanGetpin( ASSUAN_CONTEXT ctx, char* line )
100 {
101   //qDebug("PinEntryController::assuanGetpin( %s )", line );  
102   PinEntryController* that =   static_cast<PinEntryController*>(assuan_get_pointer(ctx));
103   return that->getPin( line );
104 }
105
106 int PinEntryController::getPin( char* line ) {
107   if( _pinentry == 0 ) {
108     _pinentry = new PinEntryDialog(0,0,true);
109   }
110   _pinentry->setPrompt( _prompt );
111   _pinentry->setDescription( _desc );
112   if( !_error.isNull() ) _pinentry->setError( _error );
113   connect( _pinentry, SIGNAL( accepted() ),
114            this, SLOT( slotAccepted() ) );
115   connect( _pinentry, SIGNAL( rejected() ),
116            this, SLOT( slotRejected() ) );
117   bool ret = _pinentry->exec();  
118   FILE* fp = assuan_get_data_fp( _ctx );
119   if( ret ) {
120     fputs( static_cast<const char*>(_pinentry->text().utf8()), fp );
121     return 0;
122   } else {
123     assuan_set_error( _ctx, ASSUAN_Canceled, "Dialog cancelled by user" );
124     return ASSUAN_Canceled;
125   }
126 }
127
128 int PinEntryController::assuanConfirm( ASSUAN_CONTEXT ctx, char* line )
129 {
130   //qDebug("PinEntryController::assuanConfirm( %s )", line );  
131   PinEntryController* that =   static_cast<PinEntryController*>(assuan_get_pointer(ctx));
132   return that->confirm( line );  
133 }
134
135 int PinEntryController::confirm( char* line )
136 {
137   int ret;
138   if( !_error.isNull() ) {
139     ret = KMessageBox::questionYesNo( 0, _error );
140   } else {
141     ret = KMessageBox::questionYesNo( 0, _desc );    
142   }
143   FILE* fp = assuan_get_data_fp( _ctx );
144   if( ret == KMessageBox::Yes ) {
145     fputs( "YES", fp );    
146   } else {
147     fputs( "NO", fp );
148   }
149   return 0;
150 }
151
152 void PinEntryController::slotAccepted()
153 {
154   //qDebug("PinEntryController::slotAccepted() NYI");
155   _pinentry->accept();
156 }
157
158 void PinEntryController::slotRejected()
159 {
160   //qDebug("PinEntryController::slotRejected() NYI");
161   _pinentry->reject();
162 }