- Change licensestore to XDG directory ~/.local/share/rdesktop/licenses

- Added helper functions for SHA1 hash to hash the hostname used for
  licenses filename to hide information of what host user X connects 
  from in a infrastructure with NFS mounted home directories.



git-svn-id: svn://svn.code.sf.net/p/rdesktop/code/rdesktop/trunk@1644 423420c4-83ab-492f-b58f-81f9feb106b5
This commit is contained in:
Henrik Andersson 2011-11-21 10:51:08 +00:00
parent aa517c7c39
commit 8a52bf3a9b
3 changed files with 130 additions and 18 deletions

View File

@ -176,6 +176,8 @@ void rdpsnd_queue_next(unsigned long completed_in_us);
int rdpsnd_queue_next_tick(void); int rdpsnd_queue_next_tick(void);
void rdpsnd_reset_state(void); void rdpsnd_reset_state(void);
/* secure.c */ /* secure.c */
void sec_hash_to_string(char * out, int out_size, uint8 * in, int in_size);
void sec_hash_sha1_16(uint8 * out, uint8 * in, uint8 *salt1);
void sec_hash_48(uint8 * out, uint8 * in, uint8 * salt1, uint8 * salt2, uint8 salt); void sec_hash_48(uint8 * out, uint8 * in, uint8 * salt1, uint8 * salt2, uint8 salt);
void sec_hash_16(uint8 * out, uint8 * in, uint8 * salt1, uint8 * salt2); void sec_hash_16(uint8 * out, uint8 * in, uint8 * salt1, uint8 * salt2);
void buf_out_uint32(uint8 * buffer, uint32 value); void buf_out_uint32(uint8 * buffer, uint32 value);

View File

@ -28,6 +28,7 @@
#include <sys/time.h> /* gettimeofday */ #include <sys/time.h> /* gettimeofday */
#include <sys/times.h> /* times */ #include <sys/times.h> /* times */
#include <ctype.h> /* toupper */ #include <ctype.h> /* toupper */
#include <limits.h>
#include <errno.h> #include <errno.h>
#include <signal.h> #include <signal.h>
#include "rdesktop.h" #include "rdesktop.h"
@ -49,6 +50,13 @@
#include "ssl.h" #include "ssl.h"
#define RDESKTOP_LICENSE_STORE "/.local/share/rdesktop/licenses"
uint8 g_static_rdesktop_salt_16[16] = {
0xb8, 0x82, 0x29, 0x31, 0xc5, 0x39, 0xd9, 0x44,
0x54, 0x15, 0x5e, 0x14, 0x71, 0x38, 0xd5, 0x4d
};
char g_title[64] = ""; char g_title[64] = "";
char *g_username; char *g_username;
char g_hostname[16]; char g_hostname[16];
@ -320,7 +328,7 @@ handle_disconnect_reason(RD_BOOL deactivated, uint16 reason)
break; break;
case exDiscReasonLicenseErrClientEncryption: case exDiscReasonLicenseErrClientEncryption:
text = "Incorrect client license enryption"; text = "Incorrect client license encryption";
retval = EXRD_LIC_ENC; retval = EXRD_LIC_ENC;
break; break;
@ -1493,11 +1501,72 @@ l_to_a(long N, int base)
return ret; return ret;
} }
static int
safe_mkdir(const char *path, int mask)
{
int res = 0;
struct stat st;
res = stat(path, &st);
if (res == -1 )
return mkdir(path, mask);
if (!S_ISDIR(st.st_mode))
{
errno = EEXIST;
return -1;
}
return 0;
}
static int
mkdir_p(const char *path, int mask)
{
int res;
char *ptok;
char pt[PATH_MAX];
char bp[PATH_MAX];
if (!path || strlen(path) == 0)
{
errno = EINVAL;
return -1;
}
if (strlen(path) > PATH_MAX)
{
errno = E2BIG;
return -1;
}
res = 0;
pt[0] = bp[0] = '\0';
strcpy(bp, path);
ptok = strtok(bp, "/");
if (ptok == NULL)
return safe_mkdir(path,mask);
do
{
if (ptok != bp)
strcat(pt, "/");
strcat(pt, ptok);
res = safe_mkdir(pt, mask);
if (res != 0)
return res;
} while ((ptok = strtok(NULL, "/")) != NULL);
return 0;
}
int int
load_licence(unsigned char **data) load_licence(unsigned char **data)
{ {
char *home, *path; uint8 ho[16], hi[16];
char *home, path[PATH_MAX], hash[33];
struct stat st; struct stat st;
int fd, length; int fd, length;
@ -1505,48 +1574,68 @@ load_licence(unsigned char **data)
if (home == NULL) if (home == NULL)
return -1; return -1;
path = (char *) xmalloc(strlen(home) + strlen(g_hostname) + sizeof("/.rdesktop/licence.")); snprintf((char*)hi, 16, g_hostname);
sprintf(path, "%s/.rdesktop/licence.%s", home, g_hostname); sec_hash_sha1_16(ho, hi, g_static_rdesktop_salt_16);
sec_hash_to_string(hash, 33, ho, 16);
snprintf(path, PATH_MAX, "%s"RDESKTOP_LICENSE_STORE"/%s.cal",
home, hash);
path[sizeof(path)-1] = '\0';
fd = open(path, O_RDONLY); fd = open(path, O_RDONLY);
if (fd == -1) if (fd == -1)
return -1; {
/* fallback to try reading old license file */
snprintf(path, PATH_MAX, "%s/.rdesktop/license.%s",
home, g_hostname);
path[sizeof(path)-1] = '\0';
if ((fd = open(path, O_RDONLY)) == -1)
return -1;
}
if (fstat(fd, &st)) if (fstat(fd, &st))
{
close(fd);
return -1; return -1;
}
*data = (uint8 *) xmalloc(st.st_size); *data = (uint8 *) xmalloc(st.st_size);
length = read(fd, *data, st.st_size); length = read(fd, *data, st.st_size);
close(fd); close(fd);
xfree(path);
return length; return length;
} }
void void
save_licence(unsigned char *data, int length) save_licence(unsigned char *data, int length)
{ {
char *home, *path, *tmppath; uint8 ho[16], hi[16];
char *home, path[PATH_MAX], tmppath[PATH_MAX], hash[33];
int fd; int fd;
home = getenv("HOME"); home = getenv("HOME");
if (home == NULL) if (home == NULL)
return; return;
path = (char *) xmalloc(strlen(home) + strlen(g_hostname) + sizeof("/.rdesktop/licence.")); snprintf(path, PATH_MAX, "%s"RDESKTOP_LICENSE_STORE, home);
path[sizeof(path)-1] = '\0';
sprintf(path, "%s/.rdesktop", home); if ( mkdir_p(path, 0700) == -1)
if ((mkdir(path, 0700) == -1) && errno != EEXIST)
{ {
perror(path); perror(path);
return; return;
} }
/* write licence to licence.hostname.new, then atomically rename to licence.hostname */ snprintf((char*)hi,16,g_hostname);
sec_hash_sha1_16(ho, hi, g_static_rdesktop_salt_16);
sec_hash_to_string(hash, 33, ho, 16);
sprintf(path, "%s/.rdesktop/licence.%s", home, g_hostname); /* write licence to {sha1}.cal.new, then atomically
tmppath = (char *) xmalloc(strlen(path) + sizeof(".new")); rename to {sha1}.cal */
strcpy(tmppath, path); snprintf(path, PATH_MAX, "%s"RDESKTOP_LICENSE_STORE"/%s.cal",
strcat(tmppath, ".new"); home, hash);
path[sizeof(path)-1] = '\0';
snprintf(tmppath, PATH_MAX, "%s.new", path);
path[sizeof(path)-1] = '\0';
fd = open(tmppath, O_WRONLY | O_CREAT | O_TRUNC, 0600); fd = open(tmppath, O_WRONLY | O_CREAT | O_TRUNC, 0600);
if (fd == -1) if (fd == -1)
@ -1567,8 +1656,6 @@ save_licence(unsigned char *data, int length)
} }
close(fd); close(fd);
xfree(tmppath);
xfree(path);
} }
/* Create the bitmap cache directory */ /* Create the bitmap cache directory */

View File

@ -111,6 +111,29 @@ sec_hash_16(uint8 * out, uint8 * in, uint8 * salt1, uint8 * salt2)
ssl_md5_final(&md5, out); ssl_md5_final(&md5, out);
} }
/*
* 16-byte sha1 hash
*/
void sec_hash_sha1_16(uint8 * out, uint8 * in, uint8 *salt1)
{
SSL_SHA1 sha1;
ssl_sha1_init(&sha1);
ssl_sha1_update(&sha1, in, 16);
ssl_sha1_update(&sha1, salt1, 16);
ssl_sha1_final(&sha1, out);
}
/* create string from hash */
void sec_hash_to_string(char * out, int out_size, uint8 * in, int in_size)
{
int k;
memset(out,0,out_size);
for (k=0;k<in_size;k++,out+=2)
{
sprintf(out,"%.2x",in[k]);
}
}
/* Reduce key entropy from 64 to 40 bits */ /* Reduce key entropy from 64 to 40 bits */
static void static void
sec_make_40bit(uint8 * key) sec_make_40bit(uint8 * key)