add libvncserver
[presencevnc] / libvnc / libvncserver / vncauth.c
1 /*
2  *  Copyright (C) 1999 AT&T Laboratories Cambridge.  All Rights Reserved.
3  *
4  *  This is free software; you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation; either version 2 of the License, or
7  *  (at your option) any later version.
8  *
9  *  This software is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License
15  *  along with this program; if not, write to the Free Software
16  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
17  *  USA.
18  */
19
20 /*
21  * vncauth.c - Functions for VNC password management and authentication.
22  */
23
24 #ifdef __STRICT_ANSI__
25 #define _BSD_SOURCE
26 #define _POSIX_SOURCE
27 #endif
28 #ifdef LIBVNCSERVER_HAVE_SYS_TYPES_H
29 #include <sys/types.h>
30 #endif
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <unistd.h>
34 #include <rfb/rfbproto.h>
35 #include "d3des.h"
36
37 #include <string.h>
38 #include <math.h>
39
40 #ifdef LIBVNCSERVER_HAVE_SYS_STAT_H
41 #include <sys/stat.h>
42 #endif
43
44 #include <time.h>
45
46 #ifdef WIN32
47 #define srandom srand
48 #define random rand
49 #else
50 #include <sys/time.h>
51 #endif
52
53
54 /* libvncclient does not need this */
55 #ifndef rfbEncryptBytes
56
57 /*
58  * We use a fixed key to store passwords, since we assume that our local
59  * file system is secure but nonetheless don't want to store passwords
60  * as plaintext.
61  */
62
63 static unsigned char fixedkey[8] = {23,82,107,6,35,78,88,7};
64
65
66 /*
67  * Encrypt a password and store it in a file.  Returns 0 if successful,
68  * 1 if the file could not be written.
69  */
70
71 int
72 rfbEncryptAndStorePasswd(char *passwd, char *fname)
73 {
74     FILE *fp;
75     unsigned int i;
76     unsigned char encryptedPasswd[8];
77
78     if ((fp = fopen(fname,"w")) == NULL) return 1;
79
80         /* windows security sux */
81 #ifndef WIN32
82     fchmod(fileno(fp), S_IRUSR|S_IWUSR);
83 #endif
84
85     /* pad password with nulls */
86
87     for (i = 0; i < 8; i++) {
88         if (i < strlen(passwd)) {
89             encryptedPasswd[i] = passwd[i];
90         } else {
91             encryptedPasswd[i] = 0;
92         }
93     }
94
95     /* Do encryption in-place - this way we overwrite our copy of the plaintext
96        password */
97
98     rfbDesKey(fixedkey, EN0);
99     rfbDes(encryptedPasswd, encryptedPasswd);
100
101     for (i = 0; i < 8; i++) {
102         putc(encryptedPasswd[i], fp);
103     }
104   
105     fclose(fp);
106     return 0;
107 }
108
109
110 /*
111  * Decrypt a password from a file.  Returns a pointer to a newly allocated
112  * string containing the password or a null pointer if the password could
113  * not be retrieved for some reason.
114  */
115
116 char *
117 rfbDecryptPasswdFromFile(char *fname)
118 {
119     FILE *fp;
120     int i, ch;
121     unsigned char *passwd = (unsigned char *)malloc(9);
122
123     if ((fp = fopen(fname,"r")) == NULL) return NULL;
124
125     for (i = 0; i < 8; i++) {
126         ch = getc(fp);
127         if (ch == EOF) {
128             fclose(fp);
129             return NULL;
130         }
131         passwd[i] = ch;
132     }
133
134     fclose(fp);
135
136     rfbDesKey(fixedkey, DE1);
137     rfbDes(passwd, passwd);
138
139     passwd[8] = 0;
140
141     return (char *)passwd;
142 }
143
144
145 /*
146  * Generate CHALLENGESIZE random bytes for use in challenge-response
147  * authentication.
148  */
149
150 void
151 rfbRandomBytes(unsigned char *bytes)
152 {
153     int i;
154     static rfbBool s_srandom_called = FALSE;
155
156     if (!s_srandom_called) {
157         srandom((unsigned int)time(NULL) ^ (unsigned int)getpid());
158         s_srandom_called = TRUE;
159     }
160
161     for (i = 0; i < CHALLENGESIZE; i++) {
162         bytes[i] = (unsigned char)(random() & 255);    
163     }
164 }
165
166 #endif
167
168 /*
169  * Encrypt CHALLENGESIZE bytes in memory using a password.
170  */
171
172 void
173 rfbEncryptBytes(unsigned char *bytes, char *passwd)
174 {
175     unsigned char key[8];
176     unsigned int i;
177
178     /* key is simply password padded with nulls */
179
180     for (i = 0; i < 8; i++) {
181         if (i < strlen(passwd)) {
182             key[i] = passwd[i];
183         } else {
184             key[i] = 0;
185         }
186     }
187
188     rfbDesKey(key, EN0);
189
190     for (i = 0; i < CHALLENGESIZE; i += 8) {
191         rfbDes(bytes+i, bytes+i);
192     }
193 }