/src/libvncserver/src/common/vncauth.c
Line | Count | Source |
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 | | #include <rfb/rfbproto.h> |
25 | | #ifdef __STRICT_ANSI__ |
26 | | #define _BSD_SOURCE |
27 | | #define _POSIX_SOURCE |
28 | | #define _XOPEN_SOURCE 600 |
29 | | #endif |
30 | | #ifdef LIBVNCSERVER_HAVE_SYS_TYPES_H |
31 | | #include <sys/types.h> |
32 | | #endif |
33 | | #include <stdio.h> |
34 | | #include <stdlib.h> |
35 | | #ifdef LIBVNCSERVER_HAVE_UNISTD_H |
36 | | #include <unistd.h> |
37 | | #endif |
38 | | #include "crypto.h" |
39 | | |
40 | | #include <string.h> |
41 | | #include <math.h> |
42 | | |
43 | | #ifdef LIBVNCSERVER_HAVE_SYS_STAT_H |
44 | | #include <sys/stat.h> |
45 | | #endif |
46 | | |
47 | | #include <time.h> |
48 | | |
49 | | #ifdef WIN32 |
50 | | #define srandom srand |
51 | | #define random rand |
52 | | #include <process.h> |
53 | | #ifdef _MSC_VER |
54 | | #pragma warning(disable:4996) |
55 | | #endif |
56 | | #else |
57 | | #include <sys/time.h> |
58 | | #endif |
59 | | |
60 | | |
61 | | /* libvncclient does not need this */ |
62 | | #ifndef rfbEncryptBytes |
63 | | |
64 | | /* |
65 | | * We use a fixed key to store passwords, since we assume that our local |
66 | | * file system is secure but nonetheless don't want to store passwords |
67 | | * as plaintext. |
68 | | */ |
69 | | |
70 | | static unsigned char fixedkey[8] = {23,82,107,6,35,78,88,7}; |
71 | | |
72 | | |
73 | | /* |
74 | | * Encrypt a password and store it in a file. Returns 0 if successful, |
75 | | * 1 if the file could not be written. |
76 | | */ |
77 | | |
78 | | int |
79 | | rfbEncryptAndStorePasswd(char *passwd, char *fname) |
80 | 0 | { |
81 | 0 | FILE *fp; |
82 | 0 | unsigned int i; |
83 | 0 | unsigned char encryptedPasswd[8]; |
84 | 0 | int out_len; |
85 | |
|
86 | 0 | if ((fp = fopen(fname,"w")) == NULL) return 1; |
87 | | |
88 | | /* windows security sux */ |
89 | 0 | #ifndef WIN32 |
90 | 0 | fchmod(fileno(fp), S_IRUSR|S_IWUSR); |
91 | 0 | #endif |
92 | | |
93 | | /* pad password with nulls */ |
94 | |
|
95 | 0 | for (i = 0; i < 8; i++) { |
96 | 0 | if (i < strlen(passwd)) { |
97 | 0 | encryptedPasswd[i] = passwd[i]; |
98 | 0 | } else { |
99 | 0 | encryptedPasswd[i] = 0; |
100 | 0 | } |
101 | 0 | } |
102 | | |
103 | | /* Do encryption in-place - this way we overwrite our copy of the plaintext |
104 | | password */ |
105 | 0 | encrypt_rfbdes(encryptedPasswd, &out_len, fixedkey, encryptedPasswd, sizeof(encryptedPasswd)); |
106 | |
|
107 | 0 | for (i = 0; i < 8; i++) { |
108 | 0 | putc(encryptedPasswd[i], fp); |
109 | 0 | } |
110 | |
|
111 | 0 | fclose(fp); |
112 | 0 | return 0; |
113 | 0 | } |
114 | | |
115 | | |
116 | | /* |
117 | | * Decrypt a password from a file. Returns a pointer to a newly allocated |
118 | | * string containing the password or a null pointer if the password could |
119 | | * not be retrieved for some reason. |
120 | | */ |
121 | | |
122 | | char * |
123 | | rfbDecryptPasswdFromFile(char *fname) |
124 | 0 | { |
125 | 0 | FILE *fp; |
126 | 0 | int i, ch; |
127 | 0 | unsigned char *passwd = (unsigned char *)malloc(9); |
128 | 0 | int out_len; |
129 | |
|
130 | 0 | if (!passwd || (fp = fopen(fname,"r")) == NULL) { |
131 | 0 | free(passwd); |
132 | 0 | return NULL; |
133 | 0 | } |
134 | | |
135 | 0 | for (i = 0; i < 8; i++) { |
136 | 0 | ch = getc(fp); |
137 | 0 | if (ch == EOF) { |
138 | 0 | fclose(fp); |
139 | 0 | free(passwd); |
140 | 0 | return NULL; |
141 | 0 | } |
142 | 0 | passwd[i] = ch; |
143 | 0 | } |
144 | | |
145 | 0 | fclose(fp); |
146 | |
|
147 | 0 | if(!decrypt_rfbdes(passwd, &out_len, fixedkey, passwd, 8)) |
148 | 0 | return NULL; |
149 | | |
150 | 0 | passwd[8] = 0; |
151 | |
|
152 | 0 | return (char *)passwd; |
153 | 0 | } |
154 | | |
155 | | |
156 | | /* |
157 | | * Generate CHALLENGESIZE random bytes for use in challenge-response |
158 | | * authentication. |
159 | | */ |
160 | | |
161 | | void |
162 | | rfbRandomBytes(unsigned char *bytes) |
163 | 0 | { |
164 | 0 | int i; |
165 | 0 | static rfbBool s_srandom_called = FALSE; |
166 | |
|
167 | 0 | if (!s_srandom_called) { |
168 | 0 | srandom((unsigned int)time(NULL) ^ (unsigned int)getpid()); |
169 | 0 | s_srandom_called = TRUE; |
170 | 0 | } |
171 | |
|
172 | 0 | for (i = 0; i < CHALLENGESIZE; i++) { |
173 | 0 | bytes[i] = (unsigned char)(random() & 255); |
174 | 0 | } |
175 | 0 | } |
176 | | |
177 | | #endif |
178 | | |
179 | | /* |
180 | | * Encrypt CHALLENGESIZE bytes in memory using a password. |
181 | | */ |
182 | | |
183 | | void |
184 | | rfbEncryptBytes(unsigned char *bytes, char *passwd) |
185 | 0 | { |
186 | 0 | unsigned char key[8]; |
187 | 0 | unsigned int i; |
188 | 0 | int out_len; |
189 | | |
190 | | /* key is simply password padded with nulls */ |
191 | |
|
192 | 0 | for (i = 0; i < 8; i++) { |
193 | 0 | if (i < strlen(passwd)) { |
194 | 0 | key[i] = passwd[i]; |
195 | 0 | } else { |
196 | 0 | key[i] = 0; |
197 | 0 | } |
198 | 0 | } |
199 | |
|
200 | 0 | encrypt_rfbdes(bytes, &out_len, key, bytes, CHALLENGESIZE); |
201 | 0 | } |
202 | | |
203 | | void |
204 | 0 | rfbEncryptBytes2(unsigned char *where, const int length, unsigned char *key) { |
205 | 0 | int i, j, out_len; |
206 | 0 | for (i = 0; i< 8; i++) |
207 | 0 | where[i] ^= key[i]; |
208 | 0 | encrypt_rfbdes(where, &out_len, key, where, 8); |
209 | 0 | for (i = 8; i < length; i += 8) { |
210 | 0 | for (j = 0; j < 8; j++) { |
211 | 0 | where[i + j] ^= where[i + j - 8]; |
212 | 0 | } |
213 | 0 | encrypt_rfbdes(where + i, &out_len, key, where + i, 8); |
214 | 0 | } |
215 | 0 | } |