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