comparison mcabber/src/main.c @ 1042:8a395c2cafc4

Initial PGP support (decrypt) This patch initialize the PGP (GPG) sub-system, and adds a few PGP-related options to the configuration file. Encrypted messages can be processed. Presence is signed when the status message is non-empty.
author Mikael Berthe <mikael@lilotux.net>
date Sun, 26 Nov 2006 10:42:25 +0100
parents 0759f4c7da68
children 1ec7ec9bda60
comparison
equal deleted inserted replaced
1041:d4b97a2423eb 1042:8a395c2cafc4
38 #include "roster.h" 38 #include "roster.h"
39 #include "commands.h" 39 #include "commands.h"
40 #include "histolog.h" 40 #include "histolog.h"
41 #include "hooks.h" 41 #include "hooks.h"
42 #include "utils.h" 42 #include "utils.h"
43 #include "pgp.h"
43 44
44 #ifdef ENABLE_HGCSET 45 #ifdef ENABLE_HGCSET
45 # include "hgcset.h" 46 # include "hgcset.h"
46 #endif 47 #endif
47 48
184 } else { 185 } else {
185 scr_LogPrint(LPRINT_LOGNORM, "Caught signal: %d", signum); 186 scr_LogPrint(LPRINT_LOGNORM, "Caught signal: %d", signum);
186 } 187 }
187 } 188 }
188 189
189 static void ask_password(void) 190 // ask_password(what)
191 // Return the password, or NULL.
192 // The string must be freed after use.
193 static char *ask_password(const char *what)
190 { 194 {
191 char *password, *p; 195 char *password, *p;
192 size_t passsize = 128; 196 size_t passsize = 128;
193 struct termios orig, new; 197 struct termios orig, new;
194 198
195 password = g_new0(char, passsize); 199 password = g_new0(char, passsize);
196 200
197 /* Turn echoing off and fail if we can't. */ 201 /* Turn echoing off and fail if we can't. */
198 if (tcgetattr(fileno(stdin), &orig) != 0) return; 202 if (tcgetattr(fileno(stdin), &orig) != 0) return NULL;
199 backup_termios = &orig; 203 backup_termios = &orig;
200 204
201 new = orig; 205 new = orig;
202 new.c_lflag &= ~ECHO; 206 new.c_lflag &= ~ECHO;
203 if (tcsetattr(fileno(stdin), TCSAFLUSH, &new) != 0) return; 207 if (tcsetattr(fileno(stdin), TCSAFLUSH, &new) != 0) return NULL;
204 208
205 /* Read the password. */ 209 /* Read the password. */
206 printf("Please enter password: "); 210 printf("Please enter %s: ", what);
207 fgets(password, passsize, stdin); 211 fgets(password, passsize, stdin);
208 212
209 /* Restore terminal. */ 213 /* Restore terminal. */
210 tcsetattr(fileno(stdin), TCSAFLUSH, &orig); 214 tcsetattr(fileno(stdin), TCSAFLUSH, &orig);
211 printf("\n"); 215 printf("\n");
214 for (p = (char*)password; *p; p++) 218 for (p = (char*)password; *p; p++)
215 ; 219 ;
216 for ( ; p > (char*)password ; p--) 220 for ( ; p > (char*)password ; p--)
217 if (*p == '\n' || *p == '\r') *p = 0; 221 if (*p == '\n' || *p == '\r') *p = 0;
218 222
219 settings_set(SETTINGS_TYPE_OPTION, "password", password); 223 return password;
220 g_free(password);
221 return;
222 } 224 }
223 225
224 static void credits(void) 226 static void credits(void)
225 { 227 {
226 const char *v_fmt = "MCabber %s -- Email: mcabber [at] lilotux [dot] net\n"; 228 const char *v_fmt = "MCabber %s -- Email: mcabber [at] lilotux [dot] net\n";
227 char *v = mcabber_version(); 229 char *v = mcabber_version();
228 printf(v_fmt, v); 230 printf(v_fmt, v);
229 scr_LogPrint(LPRINT_LOGNORM|LPRINT_NOTUTF8, v_fmt, v); 231 scr_LogPrint(LPRINT_LOGNORM|LPRINT_NOTUTF8, v_fmt, v);
230 g_free(v); 232 g_free(v);
233 }
234
235 void main_init_pgp(void)
236 {
237 #ifdef HAVE_GPGME
238 const char *pk, *pp;
239 char *typed_passwd = NULL;
240 char *p;
241 bool pgp_invalid = FALSE;
242 bool pgp_agent;
243
244 p = getenv("GPG_AGENT_INFO");
245 pgp_agent = (p && strchr(p, ':'));
246
247 pk = settings_opt_get("pgp_private_key");
248 pp = settings_opt_get("pgp_passphrase");
249 if (!pk) {
250 scr_LogPrint(LPRINT_LOGNORM, "WARNING: unkown PGP private key");
251 pgp_invalid = TRUE;
252 } else if (!(pp || pgp_agent)) {
253 // Request PGP passphrase
254 pp = typed_passwd = ask_password("PGP passphrase");
255 }
256 gpg_init(pk, pp);
257 // Erase password from the settings array
258 if (pp) {
259 memset((char*)pp, 0, strlen(pp));
260 if (typed_passwd)
261 g_free(typed_passwd);
262 else
263 settings_set(SETTINGS_TYPE_OPTION, "pgp_passphrase", NULL);
264 }
265 if (!pgp_agent && pk && pp && gpg_test_passphrase()) {
266 // Let's check the pasphrase
267 int i;
268 for (i = 0; i < 2; i++) {
269 typed_passwd = ask_password("PGP passphrase"); // Ask again...
270 if (typed_passwd) {
271 gpg_set_passphrase(typed_passwd);
272 memset(typed_passwd, 0, strlen(typed_passwd));
273 g_free(typed_passwd);
274 }
275 if (!gpg_test_passphrase())
276 break; // Ok
277 }
278 if (i == 2)
279 pgp_invalid = TRUE;
280 }
281 if (pgp_invalid)
282 scr_LogPrint(LPRINT_LOGNORM, "WARNING: PGP key/pass invalid");
283 #else /* not HAVE_GPGME */
284 scr_LogPrint(LPRINT_LOGNORM, "WARNING: not compiled with PGP support");
285 #endif /* HAVE_GPGME */
231 } 286 }
232 287
233 int main(int argc, char **argv) 288 int main(int argc, char **argv)
234 { 289 {
235 char *configFile = NULL; 290 char *configFile = NULL;
289 if (p) 344 if (p)
290 printf("Server: %s\n", p); 345 printf("Server: %s\n", p);
291 p = settings_opt_get("username"); 346 p = settings_opt_get("username");
292 if (p) 347 if (p)
293 printf("Username: %s\n", p); 348 printf("Username: %s\n", p);
294 ask_password(); 349 settings_set(SETTINGS_TYPE_OPTION, "password",
295 } 350 ask_password("Jabber password"));
351 }
352
353 /* Initialize PGP system
354 We do it before ncurses initialization because we may need to request
355 a passphrase. */
356 if (settings_opt_get_int("pgp"))
357 main_init_pgp();
296 358
297 /* Initialize N-Curses */ 359 /* Initialize N-Curses */
298 scr_LogPrint(LPRINT_DEBUG, "Initializing N-Curses..."); 360 scr_LogPrint(LPRINT_DEBUG, "Initializing N-Curses...");
299 scr_InitCurses(); 361 scr_InitCurses();
300 scr_DrawMainWindow(TRUE); 362 scr_DrawMainWindow(TRUE);
344 jb_main(); 406 jb_main();
345 } 407 }
346 } 408 }
347 409
348 jb_disconnect(); 410 jb_disconnect();
411 #ifdef HAVE_GPGME
412 gpg_terminate();
413 #endif
349 scr_TerminateCurses(); 414 scr_TerminateCurses();
350 415
351 printf("\n\nThanks for using mcabber!\n"); 416 printf("\n\nThanks for using mcabber!\n");
352 417
353 return 0; 418 return 0;