You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
210 lines
4.3 KiB
210 lines
4.3 KiB
/* |
|
* Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. |
|
* |
|
* This is free software; you can redistribute it and/or modify |
|
* it under the terms of the GNU General Public License as published by |
|
* the Free Software Foundation; either version 2 of the License, or |
|
* (at your option) any later version. |
|
* |
|
* This software is distributed in the hope that it will be useful, |
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
* GNU General Public License for more details. |
|
* |
|
* You should have received a copy of the GNU General Public License |
|
* along with this program; if not, write to the Free Software |
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
|
* USA. |
|
*/ |
|
|
|
/* |
|
* vncauth.c - Functions for VNC password management and authentication. |
|
*/ |
|
|
|
#ifdef LIBVNCSERVER_HAVE_SYS_TYPES_H |
|
#include <sys/types.h> |
|
#endif |
|
#include <stdio.h> |
|
#include <stdlib.h> |
|
#ifdef LIBVNCSERVER_HAVE_UNISTD_H |
|
#include <unistd.h> |
|
#endif |
|
#include <rfb/rfbproto.h> |
|
#include "d3des.h" |
|
|
|
#include <string.h> |
|
#include <math.h> |
|
|
|
#ifdef LIBVNCSERVER_HAVE_SYS_STAT_H |
|
#include <sys/stat.h> |
|
#endif |
|
|
|
#include <time.h> |
|
|
|
#ifdef WIN32 |
|
#define srandom srand |
|
#define random rand |
|
#else |
|
#include <sys/time.h> |
|
#endif |
|
|
|
|
|
/* libvncclient does not need this */ |
|
#ifndef rfbEncryptBytes |
|
|
|
/* |
|
* We use a fixed key to store passwords, since we assume that our local |
|
* file system is secure but nonetheless don't want to store passwords |
|
* as plaintext. |
|
*/ |
|
|
|
static unsigned char fixedkey[8] = {23,82,107,6,35,78,88,7}; |
|
|
|
|
|
/* |
|
* Encrypt a password and store it in a file. Returns 0 if successful, |
|
* 1 if the file could not be written. |
|
*/ |
|
|
|
int |
|
rfbEncryptAndStorePasswd(char *passwd, char *fname) |
|
{ |
|
FILE *fp; |
|
unsigned int i; |
|
unsigned char encryptedPasswd[8]; |
|
|
|
if ((fp = fopen(fname,"w")) == NULL) return 1; |
|
|
|
/* windows security sux */ |
|
#ifndef WIN32 |
|
fchmod(fileno(fp), S_IRUSR|S_IWUSR); |
|
#endif |
|
|
|
/* pad password with nulls */ |
|
|
|
for (i = 0; i < 8; i++) { |
|
if (i < strlen(passwd)) { |
|
encryptedPasswd[i] = passwd[i]; |
|
} else { |
|
encryptedPasswd[i] = 0; |
|
} |
|
} |
|
|
|
/* Do encryption in-place - this way we overwrite our copy of the plaintext |
|
password */ |
|
|
|
rfbDesKey(fixedkey, EN0); |
|
rfbDes(encryptedPasswd, encryptedPasswd); |
|
|
|
for (i = 0; i < 8; i++) { |
|
putc(encryptedPasswd[i], fp); |
|
} |
|
|
|
fclose(fp); |
|
return 0; |
|
} |
|
|
|
|
|
/* |
|
* Decrypt a password from a file. Returns a pointer to a newly allocated |
|
* string containing the password or a null pointer if the password could |
|
* not be retrieved for some reason. |
|
*/ |
|
|
|
char * |
|
rfbDecryptPasswdFromFile(char *fname) |
|
{ |
|
FILE *fp; |
|
int i, ch; |
|
unsigned char *passwd = (unsigned char *)malloc(9); |
|
|
|
if ((fp = fopen(fname,"r")) == NULL) { |
|
free(passwd); |
|
return NULL; |
|
} |
|
|
|
for (i = 0; i < 8; i++) { |
|
ch = getc(fp); |
|
if (ch == EOF) { |
|
fclose(fp); |
|
free(passwd); |
|
return NULL; |
|
} |
|
passwd[i] = ch; |
|
} |
|
|
|
fclose(fp); |
|
|
|
rfbDesKey(fixedkey, DE1); |
|
rfbDes(passwd, passwd); |
|
|
|
passwd[8] = 0; |
|
|
|
return (char *)passwd; |
|
} |
|
|
|
|
|
/* |
|
* Generate CHALLENGESIZE random bytes for use in challenge-response |
|
* authentication. |
|
*/ |
|
|
|
void |
|
rfbRandomBytes(unsigned char *bytes) |
|
{ |
|
int i; |
|
static rfbBool s_srandom_called = FALSE; |
|
|
|
if (!s_srandom_called) { |
|
srandom((unsigned int)time(NULL) ^ (unsigned int)getpid()); |
|
s_srandom_called = TRUE; |
|
} |
|
|
|
for (i = 0; i < CHALLENGESIZE; i++) { |
|
bytes[i] = (unsigned char)(random() & 255); |
|
} |
|
} |
|
|
|
#endif |
|
|
|
/* |
|
* Encrypt CHALLENGESIZE bytes in memory using a password. |
|
*/ |
|
|
|
void |
|
rfbEncryptBytes(unsigned char *bytes, char *passwd) |
|
{ |
|
unsigned char key[8]; |
|
unsigned int i; |
|
|
|
/* key is simply password padded with nulls */ |
|
|
|
for (i = 0; i < 8; i++) { |
|
if (i < strlen(passwd)) { |
|
key[i] = passwd[i]; |
|
} else { |
|
key[i] = 0; |
|
} |
|
} |
|
|
|
rfbDesKey(key, EN0); |
|
|
|
for (i = 0; i < CHALLENGESIZE; i += 8) { |
|
rfbDes(bytes+i, bytes+i); |
|
} |
|
} |
|
|
|
void |
|
rfbEncryptBytes2(unsigned char *where, const int length, unsigned char *key) { |
|
int i, j; |
|
rfbDesKey(key, EN0); |
|
for (i = 0; i< 8; i++) |
|
where[i] ^= key[i]; |
|
rfbDes(where, where); |
|
for (i = 8; i < length; i += 8) { |
|
for (j = 0; j < 8; j++) { |
|
where[i + j] ^= where[i + j - 8]; |
|
} |
|
rfbDes(where + i, where + i); |
|
} |
|
}
|
|
|