]> code.citadel.org Git - citadel.git/blob - citadel/textclient/client_passwords.c
More removal of $Id$ tags
[citadel.git] / citadel / textclient / client_passwords.c
1 /*
2  * Functions which allow the client to remember usernames and passwords for
3  * various sites.
4  *
5  * Copyright (c) 1987-2009 by the citadel.org team
6  *
7  *  This program is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License as published by
9  *  the Free Software Foundation; either version 3 of the License, or
10  *  (at your option) any later version.
11  *
12  *  This program is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *  GNU General Public License for more details.
16  *
17  *  You should have received a copy of the GNU General Public License
18  *  along with this program; if not, write to the Free Software
19  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  */
21
22 #include "sysdep.h"
23 #include <stdlib.h>
24 #include <unistd.h>
25 #include <string.h>
26 #include <ctype.h>
27 #include <pwd.h>
28 #include <sys/types.h>
29 #include <sys/stat.h>
30 #include <limits.h>
31 #include <stdio.h>
32 #include <libcitadel.h>
33 #include "citadel.h"
34 #include "citadel_ipc.h"
35 #include "commands.h"
36 #include "client_passwords.h"
37
38 #define PWFILENAME "%s/.citadel.passwords"
39
40 void determine_pwfilename(char *pwfile, size_t n) {
41         struct passwd *p;
42
43         p = getpwuid(getuid());
44         if (p == NULL) strcpy(pwfile, "");
45         snprintf(pwfile, n, PWFILENAME, p->pw_dir);
46 }
47
48
49 /*
50  * Check the password file for a host/port match; if found, stuff the user
51  * name and password into the user/pass buffers
52  */
53 void get_stored_password(
54                 char *host,
55                 char *port,
56                 char *username,
57                 char *password) {
58
59         char pwfile[PATH_MAX];
60         FILE *fp;
61         char buf[SIZ];
62         char buf64[SIZ];
63         char hostbuf[256], portbuf[256], ubuf[256], pbuf[256];
64
65         strcpy(username, "");
66         strcpy(password, "");
67
68         determine_pwfilename(pwfile, sizeof pwfile);
69         if (IsEmptyStr(pwfile)) return;
70
71         fp = fopen(pwfile, "r");
72         if (fp == NULL) return;
73         while (fgets(buf64, sizeof buf64, fp) != NULL) {
74                 CtdlDecodeBase64(buf, buf64, sizeof(buf64));
75                 extract_token(hostbuf, buf, 0, '|', sizeof hostbuf);
76                 extract_token(portbuf, buf, 1, '|', sizeof portbuf);
77                 extract_token(ubuf, buf, 2, '|', sizeof ubuf);
78                 extract_token(pbuf, buf, 3, '|', sizeof pbuf);
79
80                 if (!strcasecmp(hostbuf, host)) {
81                         if (!strcasecmp(portbuf, port)) {
82                                 strcpy(username, ubuf);
83                                 strcpy(password, pbuf);
84                         }
85                 }
86         }
87         fclose(fp);
88 }
89
90
91 /*
92  * Set (or clear) stored passwords.
93  */
94 void set_stored_password(
95                 char *host,
96                 char *port,
97                 char *username,
98                 char *password) {
99
100         char pwfile[PATH_MAX];
101         FILE *fp, *oldfp;
102         char buf[SIZ];
103         char buf64[SIZ];
104         char hostbuf[256], portbuf[256], ubuf[256], pbuf[256];
105
106         determine_pwfilename(pwfile, sizeof pwfile);
107         if (IsEmptyStr(pwfile)) return;
108
109         oldfp = fopen(pwfile, "r");
110         if (oldfp == NULL) oldfp = fopen("/dev/null", "r");
111         unlink(pwfile);
112         fp = fopen(pwfile, "w");
113         if (fp == NULL) fp = fopen("/dev/null", "w");
114         while (fgets(buf64, sizeof buf64, oldfp) != NULL) {
115                 CtdlDecodeBase64(buf, buf64, sizeof(buf64));
116                 extract_token(hostbuf, buf, 0, '|', sizeof hostbuf);
117                 extract_token(portbuf, buf, 1, '|', sizeof portbuf);
118                 extract_token(ubuf, buf, 2, '|', sizeof ubuf);
119                 extract_token(pbuf, buf, 3, '|', sizeof pbuf);
120
121                 if ( (strcasecmp(hostbuf, host)) 
122                    || (strcasecmp(portbuf, port)) ) {
123                         snprintf(buf, sizeof buf, "%s|%s|%s|%s|",
124                                 hostbuf, portbuf, ubuf, pbuf);
125                         CtdlEncodeBase64(buf64, buf, strlen(buf), 0);
126                         fprintf(fp, "%s\n", buf64);
127                 }
128         }
129         if (!IsEmptyStr(username)) {
130                 snprintf(buf, sizeof buf, "%s|%s|%s|%s|",
131                         host, port, username, password);
132                 CtdlEncodeBase64(buf64, buf, strlen(buf), 0);
133                 fprintf(fp, "%s\n", buf64);
134         }
135         fclose(oldfp);
136         fclose(fp);
137         chmod(pwfile, 0600);
138 }
139
140
141 /*
142  * Set the password if the user wants to, clear it otherwise 
143  */
144 void offer_to_remember_password(CtdlIPC *ipc,
145                 char *host,
146                 char *port,
147                 char *username,
148                 char *password) {
149
150         if (rc_remember_passwords) {
151                 if (boolprompt("Remember username/password for this site", 0)) {
152                         set_stored_password(host, port, username, password);
153                 }
154                 else {
155                         set_stored_password(host, port, "", "");
156                 }
157         }
158 }