Micro-fix from Marc Mutz
[pinentry.git] / qt / pinentrycontroller.cpp
1 /* pinentrycontroller.cpp - A secure KDE dialog for PIN entry.
2    Copyright (C) 2002 Klarälvdalens Datakonsult AB
3    Written by Steffen Hansen <steffen@klaralvdalens-datakonsult.se>.
4    
5    This program is free software; you can redistribute it and/or
6    modify it under the terms of the GNU General Public License as
7    published by the Free Software Foundation; either version 2 of the
8    License, or (at your option) any later version.
9  
10    This program is distributed in the hope that it will be useful, but
11    WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    General Public License for more details.
14  
15    You should have received a copy of the GNU General Public License
16    along with this program; if not, write to the Free Software
17    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
18    02111-1307, USA  */
19
20 #include "pinentrycontroller.h"
21 #include "pinentrydialog.h"
22 extern "C"
23 {
24 #include "memory.h"
25 }
26 #ifdef USE_KDE
27 # include <kmessagebox.h>
28 #else
29 # include <qmessagebox.h>
30 #endif
31
32 #include <stdlib.h>
33
34 PinEntryController::PinEntryController() : _pinentry( 0 )
35 {
36   int fds[2];
37   fds[0] = 0;
38   fds[1] = 1;
39   
40   assuan_set_malloc_hooks( secmem_malloc, secmem_realloc, secmem_free );
41   int rc = assuan_init_pipe_server( &_ctx, fds );
42   if( rc ) {
43     qDebug(assuan_strerror( static_cast<AssuanError>(rc) ));
44     exit(-1);
45   }
46   rc = registerCommands();
47
48   assuan_set_pointer( _ctx, this );
49 }
50
51 PinEntryController::~PinEntryController()
52 {
53   assuan_deinit_server( _ctx );
54 }
55
56 void PinEntryController::exec()
57 {
58   while( true ) {
59     int rc = assuan_accept( _ctx );
60     if( rc == -1 ) {
61       qDebug("Assuan terminated");
62       break;
63     } else if( rc ) {
64       qDebug("Assuan accept problem: %s", assuan_strerror( static_cast<AssuanError>(rc) ) );
65       break;
66     }
67     rc = assuan_process( _ctx );
68     if( rc ) {
69       qDebug("Assuan processing failed: %s", assuan_strerror( static_cast<AssuanError>(rc) ) );
70       continue;
71     }
72   }
73 }
74
75 int PinEntryController::registerCommands()
76 {
77   static struct {
78     const char *name;
79     int cmd_id;
80     int (*handler)(ASSUAN_CONTEXT, char *line);
81   } table[] = {
82     { "SETDESC",      0,  PinEntryController::assuanDesc },
83     { "SETPROMPT",    0,  PinEntryController::assuanPrompt },
84     { "SETERROR",     0,  PinEntryController::assuanError },
85     { "SETOK",        0,  PinEntryController::assuanOk },
86     { "SETCANCEL",    0,  PinEntryController::assuanCancel },
87     { "GETPIN",       0,  PinEntryController::assuanGetpin },
88     { "CONFIRM",      0,  PinEntryController::assuanConfirm },
89     { 0,0,0 }
90   };
91   int i, j, rc;
92   
93   for (i=j=0; table[i].name; i++) {
94     rc = assuan_register_command (_ctx,
95                                   table[i].cmd_id? table[i].cmd_id
96                                   : (ASSUAN_CMD_USER + j++),
97                                   table[i].name, table[i].handler);
98     if (rc) return rc;
99   }
100   return 0;
101 }
102
103 int PinEntryController::assuanDesc( ASSUAN_CONTEXT ctx, char* line )
104 {
105   //qDebug("PinEntryController::assuanDesc( %s )", line );
106   PinEntryController* that =   static_cast<PinEntryController*>(assuan_get_pointer(ctx));
107   that->_desc = QString::fromUtf8(line);
108   that->_error = QString::null;
109   return 0;
110 }
111
112 int PinEntryController::assuanPrompt( ASSUAN_CONTEXT ctx, char* line )
113 {
114   //qDebug("PinEntryController::assuanPrompt( %s )", line );
115   PinEntryController* that =   static_cast<PinEntryController*>(assuan_get_pointer(ctx));
116   that->_prompt = QString::fromUtf8(line);
117   that->_error = QString::null;
118   return 0;
119 }
120
121 int PinEntryController::assuanError( ASSUAN_CONTEXT ctx, char* line )
122 {
123   //qDebug("PinEntryController::assuanError( %s )", line );
124   PinEntryController* that =   static_cast<PinEntryController*>(assuan_get_pointer(ctx));
125   that->_error = QString::fromUtf8(line);
126   return 0;
127 }
128
129 int PinEntryController::assuanOk ( ASSUAN_CONTEXT ctx, char* line )
130 {
131   //qDebug("PinEntryController::assuanOk( %s )", line );
132   PinEntryController* that =   static_cast<PinEntryController*>(assuan_get_pointer(ctx));
133   that->_ok = QString::fromUtf8(line);
134   return 0;
135 }
136
137 int PinEntryController::assuanCancel( ASSUAN_CONTEXT ctx, char* line )
138 {
139   //qDebug("PinEntryController::assuanCancel( %s )", line );
140   PinEntryController* that =   static_cast<PinEntryController*>(assuan_get_pointer(ctx));
141   that->_cancel = QString::fromUtf8(line);
142   return 0;
143 }
144
145 int PinEntryController::assuanGetpin( ASSUAN_CONTEXT ctx, char* line )
146 {
147   //qDebug("PinEntryController::assuanGetpin( %s )", line );  
148   PinEntryController* that =   static_cast<PinEntryController*>(assuan_get_pointer(ctx));
149   return that->getPin( line );
150 }
151
152 int PinEntryController::getPin( char* line ) {
153   if( _pinentry == 0 ) {
154     _pinentry = new PinEntryDialog(0,0,true);
155   }
156   _pinentry->setPrompt( _prompt );
157   _pinentry->setDescription( _desc );
158   _pinentry->setText(QString::null);
159   if( !_ok.isNull() ) _pinentry->setOkText( _ok );
160   if( !_cancel.isNull() ) _pinentry->setCancelText( _cancel );
161   if( !_error.isNull() ) _pinentry->setError( _error );
162   connect( _pinentry, SIGNAL( accepted() ),
163            this, SLOT( slotAccepted() ) );
164   connect( _pinentry, SIGNAL( rejected() ),
165            this, SLOT( slotRejected() ) );
166   bool ret = _pinentry->exec();  
167   FILE* fp = assuan_get_data_fp( _ctx );
168   if( ret ) {
169     fputs( static_cast<const char*>(_pinentry->text().utf8()), fp );
170     return 0;
171   } else {
172     assuan_set_error( _ctx, ASSUAN_Canceled, "Dialog cancelled by user" );
173     return ASSUAN_Canceled;
174   }
175 }
176
177 int PinEntryController::assuanConfirm( ASSUAN_CONTEXT ctx, char* line )
178 {
179   //qDebug("PinEntryController::assuanConfirm( %s )", line );  
180   PinEntryController* that =   static_cast<PinEntryController*>(assuan_get_pointer(ctx));
181   return that->confirm( line );  
182 }
183
184 int PinEntryController::confirm( char* line )
185 {
186   int ret;
187 #ifdef USE_KDE
188   if( !_error.isNull() ) {
189     ret = KMessageBox::questionYesNo( 0, _error );
190   } else {
191     ret = KMessageBox::questionYesNo( 0, _desc );    
192   }
193   FILE* fp = assuan_get_data_fp( _ctx );
194   if( ret == KMessageBox::Yes ) {
195 #else
196   if( !_error.isNull() ) {
197     ret = QMessageBox::critical( 0, "", _error, QMessageBox::Yes, QMessageBox::No );
198   } else {
199     ret = QMessageBox::information( 0, "", _desc, QMessageBox::Yes, QMessageBox::No );
200   }    
201   FILE* fp = assuan_get_data_fp( _ctx );
202   if( ret == 0 ) {
203 #endif // USE_KDE
204     fputs( "YES", fp );    
205   } else {
206     fputs( "NO", fp );
207   }
208   return 0;
209 }
210
211 void PinEntryController::slotAccepted()
212 {
213   //qDebug("PinEntryController::slotAccepted() NYI");
214   _pinentry->accept();
215 }
216
217 void PinEntryController::slotRejected()
218 {
219   //qDebug("PinEntryController::slotRejected() NYI");
220   _pinentry->reject();
221 }