* Renamed decode_base64() to CtdlDecodeBase64()
[citadel.git] / citadel / client_passwords.c
1 /*
2  * $Id$
3  *
4  * Functions which allow the client to remember usernames and passwords for
5  * various sites.
6  *
7  */
8
9 #include "sysdep.h"
10 #include <stdlib.h>
11 #include <unistd.h>
12 #include <string.h>
13 #include <ctype.h>
14 #include <pwd.h>
15 #include <sys/types.h>
16 #include <sys/stat.h>
17 #include <limits.h>
18 #include <stdio.h>
19 #include "citadel.h"
20 #include "tools.h"
21 #include "commands.h"
22
23 #define PWFILENAME "%s/.citadel.passwords"
24
25 static void determine_pwfilename(char *pwfile, size_t n) {
26         struct passwd *p;
27
28         p = getpwuid(getuid());
29         if (p == NULL) strcpy(pwfile, "");
30         snprintf(pwfile, n, PWFILENAME, p->pw_dir);
31 }
32
33
34 /*
35  * Check the password file for a host/port match; if found, stuff the user
36  * name and password into the user/pass buffers
37  */
38 void get_stored_password(
39                 char *host,
40                 char *port,
41                 char *username,
42                 char *password) {
43
44         char pwfile[PATH_MAX];
45         FILE *fp;
46         char buf[SIZ];
47         char buf64[SIZ];
48         char hostbuf[SIZ], portbuf[SIZ], ubuf[SIZ], pbuf[SIZ];
49
50         strcpy(username, "");
51         strcpy(password, "");
52
53         determine_pwfilename(pwfile, sizeof pwfile);
54         if (strlen(pwfile)==0) return;
55
56         fp = fopen(pwfile, "r");
57         if (fp == NULL) return;
58         while (fgets(buf64, sizeof buf64, fp) != NULL) {
59                 CtdlDecodeBase64(buf, buf64, sizeof(buf64));
60                 extract(hostbuf, buf, 0);
61                 extract(portbuf, buf, 1);
62                 extract(ubuf, buf, 2);
63                 extract(pbuf, buf, 3);
64
65                 if (!strcasecmp(hostbuf, host)) {
66                         if (!strcasecmp(portbuf, port)) {
67                                 strcpy(username, ubuf);
68                                 strcpy(password, pbuf);
69                         }
70                 }
71         }
72         fclose(fp);
73 }
74
75
76 /*
77  * Set (or clear) stored passwords.
78  */
79 void set_stored_password(
80                 char *host,
81                 char *port,
82                 char *username,
83                 char *password) {
84
85         char pwfile[PATH_MAX];
86         FILE *fp, *oldfp;
87         char buf[SIZ];
88         char buf64[SIZ];
89         char hostbuf[SIZ], portbuf[SIZ], ubuf[SIZ], pbuf[SIZ];
90
91         determine_pwfilename(pwfile, sizeof pwfile);
92         if (strlen(pwfile)==0) return;
93
94         oldfp = fopen(pwfile, "r");
95         if (oldfp == NULL) oldfp = fopen("/dev/null", "r");
96         unlink(pwfile);
97         fp = fopen(pwfile, "w");
98         if (fp == NULL) fp = fopen("/dev/null", "w");
99         while (fgets(buf64, sizeof buf64, oldfp) != NULL) {
100                 CtdlDecodeBase64(buf, buf64, sizeof(buf64));
101                 extract(hostbuf, buf, 0);
102                 extract(portbuf, buf, 1);
103                 extract(ubuf, buf, 2);
104                 extract(pbuf, buf, 3);
105
106                 if ( (strcasecmp(hostbuf, host)) 
107                    || (strcasecmp(portbuf, port)) ) {
108                         snprintf(buf, sizeof buf, "%s|%s|%s|%s|",
109                                 hostbuf, portbuf, ubuf, pbuf);
110                         encode_base64(buf64, buf);
111                         fprintf(fp, "%s\n", buf64);
112                 }
113         }
114         if (strlen(username) > 0) {
115                 snprintf(buf, sizeof buf, "%s|%s|%s|%s|",
116                         host, port, username, password);
117                 encode_base64(buf64, buf);
118                 fprintf(fp, "%s\n", buf64);
119         }
120         fclose(oldfp);
121         fclose(fp);
122         chmod(pwfile, 0600);
123 }
124
125
126 /*
127  * Set the password if the user wants to, clear it otherwise 
128  */
129 void offer_to_remember_password(
130                 char *host,
131                 char *port,
132                 char *username,
133                 char *password) {
134
135         if (rc_remember_passwords) {
136                 if (boolprompt("Remember username/password for this site", 0)) {
137                         set_stored_password(host, port, username, password);
138                 }
139                 else {
140                         set_stored_password(host, port, "", "");
141                 }
142         }
143 }