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