⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mbus_config.c

📁 MPEG-4编解码的实现(包括MPEG4视音频编解码)
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 * FILE:     mbus_config.c
 * AUTHOR:   Colin Perkins
 * MODIFIED: Orion Hodson
 *           Markus Germeier
 * 
 * Copyright (c) 1999-2001 University College London
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, is permitted provided that the following conditions 
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *      This product includes software developed by the Computer Science
 *      Department at University College London
 * 4. Neither the name of the University nor of the Department may be used
 *    to endorse or promote products derived from this software without
 *    specific prior written permission.
 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#include "config_unix.h"
#include "config_win32.h"
#include "debug.h"
#include "memory.h"
#include "crypt_random.h"
#include "base64.h"
#include "mbus.h"
#include "mbus_config.h"

#define MBUS_ENCRYPT_BY_DEFAULT
#define MBUS_ENCRKEY_LEN      8
#define MBUS_HASHKEY_LEN     12
#define MBUS_BUF_SIZE	   1500
#define MBUS_FILE_NAME   ".mbus"
#define MBUS_FILE_NAME_LEN    5

struct mbus_config {
#ifdef WIN32
	HKEY		  cfgKey;
#else
	fd_t		  cfgfd;
#endif
	int		  cfg_locked;
};

char *mbus_new_encrkey(void)
{
	char		*key;	/* The key we are going to return... */
#ifdef MBUS_ENCRYPT_BY_DEFAULT
	/* Create a new key, for use by the hashing routines. Returns */
	/* a key of the form (DES,MTIzMTU2MTg5MTEyMQ==)               */
	char		 random_string[MBUS_ENCRKEY_LEN];
	char		 encoded_string[(MBUS_ENCRKEY_LEN*4/3)+4];
	int		 encoded_length;
	int		 i, j, k;

	/* Step 1: generate a random string for the key... */
	for (i = 0; i < MBUS_ENCRKEY_LEN; i++) {
		random_string[i] = ((int32_t)lbl_random() | 0x000ff000) >> 24;
	}

	/* Step 2: fill in parity bits to make DES library happy */
	for (i = 0; i < MBUS_ENCRKEY_LEN; ++i) {
	        k = random_string[i] & 0xfe;
		j = k;
		j ^= j >> 4;
		j ^= j >> 2;
		j ^= j >> 1;
		j = (j & 1) ^ 1;
		random_string[i] = k | j;
	}

	/* Step 3: base64 encode that string... */
	memset(encoded_string, 0, (MBUS_ENCRKEY_LEN*4/3)+4);
	encoded_length = base64encode(random_string, MBUS_ENCRKEY_LEN, encoded_string, (MBUS_ENCRKEY_LEN*4/3)+4);

	/* Step 4: put it all together to produce the key... */
	key = (char *) xmalloc(encoded_length + 18);
	sprintf(key, "(DES,%s)", encoded_string);
#else
	key = (char *) xmalloc(9);
	sprintf(key, "(NOENCR)");
#endif
	return key;
}

char *mbus_new_hashkey(void)
{
	/* Create a new key, for use by the hashing routines. Returns  */
	/* a key of the form (HMAC-MD5-96,MTIzMTU2MTg5MTEyMQ==)           */
	char		 random_string[MBUS_HASHKEY_LEN];
	char		 encoded_string[(MBUS_HASHKEY_LEN*4/3)+4];
	int		 encoded_length;
	int		 i;
	char		*key;

	/* Step 1: generate a random string for the key... */
	for (i = 0; i < MBUS_HASHKEY_LEN; i++) {
		random_string[i] = ((int32_t)lbl_random() | 0x000ff000) >> 24;
	}
	/* Step 2: base64 encode that string... */
	memset(encoded_string, 0, (MBUS_HASHKEY_LEN*4/3)+4);
	encoded_length = base64encode(random_string, MBUS_HASHKEY_LEN, encoded_string, (MBUS_HASHKEY_LEN*4/3)+4);

	/* Step 3: put it all together to produce the key... */
	key = (char *) xmalloc(encoded_length + 26);
	sprintf(key, "(HMAC-MD5-96,%s)", encoded_string);

	return key;
}

static void rewrite_config(struct mbus_config *m)
{
#ifdef WIN32
	char		*hashkey = mbus_new_hashkey();
	char		*encrkey = mbus_new_encrkey();
	char		*scope   = MBUS_DEFAULT_SCOPE_NAME;
	const uint32_t	 cver    = MBUS_CONFIG_VERSION;
	const uint32_t	 port    = MBUS_DEFAULT_NET_PORT;
	char		*addr    = xstrdup(MBUS_DEFAULT_NET_ADDR);
	char		 buffer[MBUS_BUF_SIZE];
	LONG		 status;

	status = RegSetValueEx(m->cfgKey, "CONFIG_VERSION", 0, REG_DWORD, (const uint8_t *) &cver, sizeof(cver));
	if (status != ERROR_SUCCESS) {
		FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, status, 0, buffer, MBUS_BUF_SIZE, NULL);
		debug_msg("Unable to set version: %s\n", buffer);
		abort();
	}
	status = RegSetValueEx(m->cfgKey, "HASHKEY", 0, REG_SZ, hashkey, strlen(hashkey) + 1);
	if (status != ERROR_SUCCESS) {
		FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, status, 0, buffer, MBUS_BUF_SIZE, NULL);
		debug_msg("Unable to set hashkey: %s\n", buffer);
		abort();
	}	
	status = RegSetValueEx(m->cfgKey, "ENCRYPTIONKEY", 0, REG_SZ, encrkey, strlen(encrkey) + 1);
	if (status != ERROR_SUCCESS) {
		FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, status, 0, buffer, MBUS_BUF_SIZE, NULL);
		debug_msg("Unable to set encrkey: %s\n", buffer);
		abort();
	}	
	status = RegSetValueEx(m->cfgKey, "SCOPE", 0, REG_SZ, scope, strlen(scope) + 1);
	if (status != ERROR_SUCCESS) {
		FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, status, 0, buffer, MBUS_BUF_SIZE, NULL);
		debug_msg("Unable to set scope: %s\n", buffer);
		abort();
	}	
	status = RegSetValueEx(m->cfgKey, "ADDRESS", 0, REG_SZ, addr, strlen(addr) + 1);
	if (status != ERROR_SUCCESS) {
		FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, status, 0, buffer, MBUS_BUF_SIZE, NULL);
		debug_msg("Unable to set address: %s\n", buffer);
		abort();
	}	
	status = RegSetValueEx(m->cfgKey, "PORT", 0, REG_DWORD, (const uint8_t *) &port, sizeof(port));
	if (status != ERROR_SUCCESS) {
		FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, status, 0, buffer, MBUS_BUF_SIZE, NULL);
		debug_msg("Unable to set port: %s\n", buffer);
		abort();
	}	
	xfree(addr);
#else
	char	*hashkey = mbus_new_hashkey();
	char	*encrkey = mbus_new_encrkey();
	char	 buf[1024];

	if (lseek(m->cfgfd, 0, SEEK_SET) == -1) {
		perror("Can't seek to start of config file");
		abort();
	}
	sprintf(buf, "[MBUS]\nCONFIG_VERSION=%d\nHASHKEY=%s\nENCRYPTIONKEY=%s\nSCOPE=%s\nADDRESS=%s\nPORT=%d\n", 
		MBUS_CONFIG_VERSION, hashkey, encrkey, MBUS_DEFAULT_SCOPE_NAME, MBUS_DEFAULT_NET_ADDR, MBUS_DEFAULT_NET_PORT);
	write(m->cfgfd, buf, strlen(buf));
	free(hashkey);
	xfree(encrkey);
#endif
}

void mbus_lock_config_file(struct mbus_config *m)
{
#ifdef WIN32
	/* Open the registry and create the mbus entries if they don't exist   */
	/* already. The default contents of the registry are random encryption */
	/* and authentication keys, and node local scope.                      */
	HKEY			key    = HKEY_CURRENT_USER;
	LPCTSTR			subKey = "Software\\Mbone Applications\\mbus";
	DWORD			disp;
	char			buffer[MBUS_BUF_SIZE];
	LONG			status;

	status = RegCreateKeyEx(key, subKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &(m->cfgKey), &disp);
	if (status != ERROR_SUCCESS) {
		FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, status, 0, buffer, MBUS_BUF_SIZE, NULL);
		debug_msg("Unable to open registry: %s\n", buffer);
		abort();
	}
	if (disp == REG_CREATED_NEW_KEY) {
		rewrite_config(m);
		debug_msg("Created new registry entry...\n");
	} else {
		debug_msg("Opened existing registry entry...\n");
	}
#else
	/* Obtain a valid lock on the mbus configuration file. This function */
	/* creates the file, if one does not exist. The default contents of  */
	/* this file are random authentication and encryption keys, and node */
	/* local scope.                                                      */
	struct flock	 l;
	struct stat	 s;
	char		*buf;
	char		*cfg_file;
	char            *cfg_loc;
	int              cfg_loc_len;

	cfg_loc = getenv("MBUS");
	if (cfg_loc == NULL) {
                cfg_loc = getenv("HOME");
                if (cfg_loc == NULL) {
                        /* The getpwuid() stuff is to determine the users    */
                        /* home directory, into which we write a .mbus       */
                        /* config file. The struct returned by getpwuid() is */
                        /* statically allocated, so it's not necessary to    */
                        /* free it afterwards.                               */
                        struct passwd	*p;	
                        p = getpwuid(getuid());
                        if (p == NULL) {
                                perror("Unable to get passwd entry");
                                abort();	      
                        }
                        cfg_loc = p->pw_dir;
                }
	}

	/* Check if config_loc is terminated by mbus config file name. If    */
        /* it's not add it.  This is allows environment variable MBUS to     */
        /* point to config file of directory of config file.                 */
        cfg_loc_len = strlen(cfg_loc);
	if (cfg_loc_len < MBUS_FILE_NAME_LEN ||
	    strcmp(cfg_loc + cfg_loc_len - MBUS_FILE_NAME_LEN, MBUS_FILE_NAME)){
                /* File location does not include config file name.          */
                cfg_file = (char*)xmalloc(cfg_loc_len + MBUS_FILE_NAME_LEN + 2);
                sprintf(cfg_file, "%s/%s", cfg_loc, MBUS_FILE_NAME);	
	} else {
                cfg_file = xstrdup(cfg_loc);
	}
        
	m->cfgfd = open(cfg_file, O_RDWR | O_CREAT, 0600);
	if (m->cfgfd == -1) {
		perror("Unable to open mbus configuration file");
		abort();
	}

	/* We attempt to get a lock on the config file, blocking until  */
	/* the lock can be obtained. The only time this should block is */
	/* when another instance of this code has a write lock on the   */
	/* file, because the contents are being updated.                */
	l.l_type   = F_WRLCK;
	l.l_start  = 0;
	l.l_whence = SEEK_SET;
	l.l_len    = 0;
	if (fcntl(m->cfgfd, F_SETLKW, &l) == -1) {
		perror("Unable to lock mbus configuration file");
		printf("The most likely reason for this error is that %s\n", cfg_file);
		printf("is on an NFS filestore, and you have not correctly setup file locking. \n");
		printf("Ask your system administrator to ensure that rpc.lockd and/or rpc.statd\n");
		printf("are running. \n");
		abort();
	}

	xfree(cfg_file);

	if (fstat(m->cfgfd, &s) != 0) {
		perror("Unable to stat config file\n");
		abort();
	}
	if (s.st_size == 0) {
		/* Empty file, create with sensible defaults... */
		rewrite_config(m);
	} else {
		/* Read in the contents of the config file... */
		buf = (char *) xmalloc(s.st_size+1);
		memset(buf, '\0', s.st_size+1);
		if (read(m->cfgfd, buf, s.st_size) != s.st_size) {
			perror("Unable to read config file\n");
			abort();
		}
		/* Check that the file contains sensible information...   */
		/* This is rather a pathetic check, but it'll do for now! */
		if (strncmp(buf, "[MBUS]", 6) != 0) {
			debug_msg("Mbus config file has incorrect header\n");
			abort();
		}
		xfree(buf);
	}
#endif
	m->cfg_locked = TRUE;
	if (mbus_get_version(m) < MBUS_CONFIG_VERSION) {
		rewrite_config(m);
		debug_msg("Updated Mbus configuration database.\n");
	}
	if (mbus_get_version(m) > MBUS_CONFIG_VERSION) {
		debug_msg("Mbus configuration database has later version number than expected.\n");
		debug_msg("Continuing, in the hope that the extensions are backwards compatible.\n");
	}
}

void mbus_unlock_config_file(struct mbus_config *m)
{
#ifdef WIN32
	LONG status;
	char buffer[MBUS_BUF_SIZE];
	
	status = RegCloseKey(m->cfgKey);
	if (status != ERROR_SUCCESS) {
		FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, status, 0, buffer, MBUS_BUF_SIZE, NULL);
		debug_msg("Unable to close registry: %s\n", buffer);
		abort();
	}
	debug_msg("Closed registry entry...\n");
#else
	struct flock	l;

	l.l_type   = F_UNLCK;
	l.l_start  = 0;
	l.l_whence = SEEK_SET;
	l.l_len    = 0;
	if (fcntl(m->cfgfd, F_SETLKW, &l) == -1) {
		perror("Unable to unlock mbus configuration file");
		abort();
	}
	close(m->cfgfd);
	m->cfgfd = -1;
#endif
	m->cfg_locked = FALSE;
}

#ifndef WIN32
static void mbus_get_key(struct mbus_config *m, struct mbus_key *key, const char *id)
{
	struct stat	 s;
	char		*buf;
	char		*line;
	char		*tmp;
	int		 pos;
        int              linepos;

	ASSERT(m->cfg_locked);

	if (lseek(m->cfgfd, 0, SEEK_SET) == -1) {
		perror("Can't seek to start of config file");
		abort();
	}
	if (fstat(m->cfgfd, &s) != 0) {
		perror("Unable to stat config file\n");
		abort();
	}
	/* Read in the contents of the config file... */
	buf = (char *) xmalloc(s.st_size+1);
	memset(buf, '\0', s.st_size+1);
	if (read(m->cfgfd, buf, s.st_size) != s.st_size) {
		perror("Unable to read config file\n");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -