Back to index

citadel  8.12
client_passwords.c
Go to the documentation of this file.
00001 /*
00002  * Functions which allow the client to remember usernames and passwords for
00003  * various sites.
00004  *
00005  * Copyright (c) 1987-2012 by the citadel.org team
00006  *
00007  *  This program is open source software; you can redistribute it and/or modify
00008  *  it under the terms of the GNU General Public License version 3.
00009  *
00010  *  This program is distributed in the hope that it will be useful,
00011  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  *  GNU General Public License for more details.
00014  */
00015 
00016 #include "sysdep.h"
00017 #include <stdlib.h>
00018 #include <unistd.h>
00019 #include <string.h>
00020 #include <ctype.h>
00021 #include <pwd.h>
00022 #include <sys/types.h>
00023 #include <sys/stat.h>
00024 #include <limits.h>
00025 #include <stdio.h>
00026 #include <libcitadel.h>
00027 #include "citadel.h"
00028 #include "citadel_ipc.h"
00029 #include "commands.h"
00030 #include "client_passwords.h"
00031 
00032 #define PWFILENAME "%s/.citadel.passwords"
00033 
00034 void determine_pwfilename(char *pwfile, size_t n) {
00035        struct passwd *p;
00036 
00037        p = getpwuid(getuid());
00038        if (p == NULL) strcpy(pwfile, "");
00039        snprintf(pwfile, n, PWFILENAME, p->pw_dir);
00040 }
00041 
00042 
00043 /*
00044  * Check the password file for a host/port match; if found, stuff the user
00045  * name and password into the user/pass buffers
00046  */
00047 void get_stored_password(
00048               char *host,
00049               char *port,
00050               char *username,
00051               char *password) {
00052 
00053        char pwfile[PATH_MAX];
00054        FILE *fp;
00055        char buf[SIZ];
00056        char buf64[SIZ];
00057        char hostbuf[256], portbuf[256], ubuf[256], pbuf[256];
00058 
00059        strcpy(username, "");
00060        strcpy(password, "");
00061 
00062        determine_pwfilename(pwfile, sizeof pwfile);
00063        if (IsEmptyStr(pwfile)) return;
00064 
00065        fp = fopen(pwfile, "r");
00066        if (fp == NULL) return;
00067        while (fgets(buf64, sizeof buf64, fp) != NULL) {
00068               CtdlDecodeBase64(buf, buf64, sizeof(buf64));
00069               extract_token(hostbuf, buf, 0, '|', sizeof hostbuf);
00070               extract_token(portbuf, buf, 1, '|', sizeof portbuf);
00071               extract_token(ubuf, buf, 2, '|', sizeof ubuf);
00072               extract_token(pbuf, buf, 3, '|', sizeof pbuf);
00073 
00074               if (!strcasecmp(hostbuf, host)) {
00075                      if (!strcasecmp(portbuf, port)) {
00076                             strcpy(username, ubuf);
00077                             strcpy(password, pbuf);
00078                      }
00079               }
00080        }
00081        fclose(fp);
00082 }
00083 
00084 
00085 /*
00086  * Set (or clear) stored passwords.
00087  */
00088 void set_stored_password(
00089               char *host,
00090               char *port,
00091               char *username,
00092               char *password) {
00093 
00094        char pwfile[PATH_MAX];
00095        FILE *fp, *oldfp;
00096        char buf[SIZ];
00097        char buf64[SIZ];
00098        char hostbuf[256], portbuf[256], ubuf[256], pbuf[256];
00099 
00100        determine_pwfilename(pwfile, sizeof pwfile);
00101        if (IsEmptyStr(pwfile)) return;
00102 
00103        oldfp = fopen(pwfile, "r");
00104        if (oldfp == NULL) oldfp = fopen("/dev/null", "r");
00105        unlink(pwfile);
00106        fp = fopen(pwfile, "w");
00107        if (fp == NULL) fp = fopen("/dev/null", "w");
00108        while (fgets(buf64, sizeof buf64, oldfp) != NULL) {
00109               CtdlDecodeBase64(buf, buf64, sizeof(buf64));
00110               extract_token(hostbuf, buf, 0, '|', sizeof hostbuf);
00111               extract_token(portbuf, buf, 1, '|', sizeof portbuf);
00112               extract_token(ubuf, buf, 2, '|', sizeof ubuf);
00113               extract_token(pbuf, buf, 3, '|', sizeof pbuf);
00114 
00115               if ( (strcasecmp(hostbuf, host)) 
00116                  || (strcasecmp(portbuf, port)) ) {
00117                      snprintf(buf, sizeof buf, "%s|%s|%s|%s|",
00118                             hostbuf, portbuf, ubuf, pbuf);
00119                      CtdlEncodeBase64(buf64, buf, strlen(buf), 0);
00120                      fprintf(fp, "%s\n", buf64);
00121               }
00122        }
00123        if (!IsEmptyStr(username)) {
00124               snprintf(buf, sizeof buf, "%s|%s|%s|%s|",
00125                      host, port, username, password);
00126               CtdlEncodeBase64(buf64, buf, strlen(buf), 0);
00127               fprintf(fp, "%s\n", buf64);
00128        }
00129        fclose(oldfp);
00130        fclose(fp);
00131        chmod(pwfile, 0600);
00132 }
00133 
00134 
00135 /*
00136  * Set the password if the user wants to, clear it otherwise 
00137  */
00138 void offer_to_remember_password(CtdlIPC *ipc,
00139               char *host,
00140               char *port,
00141               char *username,
00142               char *password) {
00143 
00144        if (rc_remember_passwords) {
00145               if (boolprompt("Remember username/password for this site", 0)) {
00146                      set_stored_password(host, port, username, password);
00147               }
00148               else {
00149                      set_stored_password(host, port, "", "");
00150               }
00151        }
00152 }