예제 #1
0
static int updatePassFile(char *passFile)
{
	User	*up;
	char	tempFile[MPR_MAX_FNAME];
	int		fd;

	mprMakeTempFileName(tempFile, sizeof(tempFile), "httpPass", 1);
	fd = open(tempFile, O_CREAT | O_TRUNC | O_WRONLY | O_TEXT, 0664);
	if (fd < 0) {
		mprError(MPR_L, MPR_USER, "Can't open %s\n", tempFile);
		return MPR_ERR_CANT_OPEN;
	}
	up = (User*) users.getFirst();
	while (up) {
		if (mprFprintf(fd, "%d: %s: %s: %s\n", up->getEnabled(), up->getName(), 
				up->getRealm(), up->getPassword()) < 0) {
			mprError(MPR_L, MPR_USER, "Can't write to %s\n", tempFile);
			return MPR_ERR_CANT_WRITE;
		}
		up = (User*) users.getNext(up);
	}
	close(fd);
	unlink(passFile);
	if (rename(tempFile, passFile) < 0) {
		mprError(MPR_L, MPR_USER, "Can't rename %s to %s\n", tempFile, 
			passFile);
		return MPR_ERR_CANT_WRITE;
	}
	return 0;
}
예제 #2
0
static void addUser(char *user, char *realm, char *password, bool enabled)
{
	User	*up;

	up = (User*) users.getFirst();
	while (up) {
		if (strcmp(user, up->getName()) == 0 && 
				strcmp(realm, up->getRealm()) == 0) {
			up->setPassword(password);
			return;
		}
		up = (User*) users.getNext(up);
	}
	users.insert(new User(user, realm, password, enabled));
}
예제 #3
0
static void readEventWrapper(void *data, MprSocket *sp, int mask, 
	int isPoolThread)
{
	MaClient	*cp;
	int			moreData, loopCount;

	mprLog(5, "%d: readEventWrapper: mask %x, isPool %d\n", 
		sp->getFd(), mask, isPoolThread);

	//
	//	Make sure we are not being deleted
	//
	mprGetMpr()->lock();
	cp = (MaClient*) clients.getFirst();
	while (cp) {
		if (cp == (MaClient*) data) {
			break;
		}
		cp = (MaClient*) clients.getNext(cp);
	}

	if (cp == 0) {
		mprError(MPR_L, MPR_LOG, "Client deleted prematurely.");
		return;
	}
	cp->lock();
	mprGetMpr()->unlock();

	//
	//	If we are multi-threaded and called on a pool thread, we can block and
	//	read as much data as we can. If single threaded, just do 25 reads.
	//
	loopCount = 25;
	do {
		moreData = cp->readEvent();

		if (cp->getState() == MPR_HTTP_CLIENT_DONE) {
			cp->signalComplete();
			break;
		}

	} while (moreData > 0 && (isPoolThread || loopCount-- > 0));

	cp->unlock();
}
예제 #4
0
MprCond::~MprCond()
{
	mutex->lock();
	pthread_cond_destroy(&cv);
#if BLD_DEBUG
	condList.remove(&link);
#endif
	delete mutex;
}
예제 #5
0
MprCond::MprCond()
{
	memset(&cv, 0, sizeof(cv));
	mutex = new MprMutex();
	triggered = 0;
	pthread_cond_init(&cv, NULL);
#if BLD_DEBUG
	condList.insert(&link);
#endif
}
예제 #6
0
MprMutex::~MprMutex()
{
	pthread_mutex_unlock(&cs);
	pthread_mutex_destroy(&cs);
#if BLD_DEBUG
	pthread_mutex_lock(&listLock);
	mutexList.remove(&link);
	pthread_mutex_unlock(&listLock);
#endif
}
예제 #7
0
MprMutex::MprMutex()
{
	pthread_mutexattr_t		attr;

	pthread_mutexattr_init(&attr);
	pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE_NP);
	memset(&cs, 0, sizeof(cs));
	pthread_mutex_init(&cs, &attr);
	pthread_mutexattr_destroy(&attr);

#if BLD_DEBUG
	pthread_mutex_lock(&listLock);
	mutexList.insert(&link);
	pthread_mutex_unlock(&listLock);
#endif
}
예제 #8
0
static int readPassFile(char *passFile)
{
	FILE	*fp;
	char	buf[MPR_HTTP_MAX_PASS * 2];
	char	*tok, *enabledSpec, *user, *realm, *password;
	bool	enabled;
	int		line;

	fp = fopen(passFile, "r" MPR_TEXT);
	if (fp == 0) {
		mprError(MPR_L, MPR_USER, "Can't open %s\n", passFile);
		return MPR_ERR_CANT_OPEN;
	}
	line = 0;
	while (fgets(buf, sizeof(buf), fp) != 0) {
		line++;
		enabledSpec = mprStrTok(buf, ":", &tok);
		user = mprStrTok(0, ":", &tok);
		realm = mprStrTok(0, ":", &tok);
		password = mprStrTok(0, "\n\r", &tok);
		if (enabledSpec == 0 || user == 0 || realm == 0 || password == 0) {
			mprError(MPR_L, MPR_USER, 
				"Badly formed password on line %d\n", line);
			return MPR_ERR_CANT_OPEN;
		}
		user = trimWhiteSpace(user);
		if (*user == '#' || *user == '\0') {
			continue;
		}
		enabled = (enabledSpec[0] == '1'); 
		
		realm = trimWhiteSpace(realm);
		password = trimWhiteSpace(password);

		users.insert(new User(user, realm, password, enabled));
	}
	fclose(fp);
	return 0;
}
예제 #9
0
MprThreadService::~MprThreadService()
{
	lock();
	//
	//	We expect users who created the threads to delete them prior to this
	//
	delete mainThread;
	delete mutex;
	mutex = 0;

#if BLD_DEBUG
	if (threads.getNumItems() > 0) {
		mprError(MPR_L, MPR_LOG, "Exiting with %d thread(s) unfreed", 
			threads.getNumItems());
	}
	if (condList.getNumItems() > 0) {
		mprError(MPR_L, MPR_LOG, "Exiting with %d cond var(s) unfreed", 
			condList.getNumItems());
	}

	pthread_mutex_lock(&listLock);
	if (mutexList.getNumItems() > 0) {
		mprError(MPR_L, MPR_LOG, "Exiting with %d mutex(es) unfreed", 
			mutexList.getNumItems() - 0);

		MprMutex *mp;
		mp = (MprMutex*) mutexList.getFirst();
		while (mp) {
			mprLog(0, "Mutex %x unfreed\n", mp);
			mp = (MprMutex*) mutexList.getNext(&mp->link);
		}
	}
	pthread_mutex_unlock(&listLock);
	pthread_mutex_destroy(&listLock);
#endif
}
예제 #10
0
static int configureViaApi()
{
	MaHostAddress 	*address;
	MaHost			*host;
	MprList			*listens;
	MaListen		*lp;
	MprHashTable	*hostAddresses;
	MaDir			*dir;
	MaAlias			*ap;
	MaLocation		*loc;
	char			*cp, *docRootPath;
	char			addrBuf[MPR_MAX_IP_ADDR_PORT], pathBuf[MPR_MAX_FNAME];
	int				port;

	mprLog(MPR_CONFIG, "Configuration via Command Line\n");

#if BLD_FEATURE_ROMFS
	mprLog(MPR_CONFIG, "Server Root \"%s\" in ROM\n", serverRoot);
	docRootPath = mprStrdup(docRoot);
#else
	//
	//	Set the document root. Is relative to the server root unless an absolute path is used.
	//	
#if WIN
	if (*docRoot != '/' && docRoot[1] != ':' && docRoot[2] != '/') 
#elif WINCE
	if (*docRoot != '\\' && docRoot != '/')
#else
	if (*docRoot != '/')
#endif
	{
        if (*docRoot) {
            mprAllocSprintf(&docRootPath, MPR_MAX_FNAME, "%s/%s", serverRoot, docRoot);
        } else {
            docRootPath = mprStrdup(serverRoot);
        }
	} else {
		docRootPath = mprStrdup(docRoot);
	}
#endif // BLD_FEATURE_ROMFS

	mprLog(MPR_CONFIG, "Document Root \"%s\"\n", docRootPath);

	//
	//	Setup the listening addresses. If only a port is specified, listen on
	//	all interfaces. If only the IP address is specified without a port,
	//	then default to port 80. IF autoScan is on, scan for a free port
	//	starting from the base address.
	//
	listens = server->getListens();

	port = MA_SERVER_DEFAULT_PORT_NUM;
	if ((cp = strchr(ipAddr, ':')) != 0) {
		*cp++ = '\0';
		port = atoi(cp);
		if (port <= 0 || port > 65535) {
			mprError(MPR_L, MPR_USER, "Bad listen port number %d", port);
			return MPR_ERR_BAD_SYNTAX;
		}
		if (autoScan) {
			port = findFreePort(ipAddr, port);
		}
		listens->insert(new MaListen(ipAddr, port, 0));

	} else {
		if (isdigit((uchar) *ipAddr) && strchr(ipAddr, '.') == 0) {
			port = atoi(ipAddr);
			if (port <= 0 || port > 65535) {
				mprError(MPR_L, MPR_USER, "Bad listen port number %d", port);
				return MPR_ERR_BAD_SYNTAX;
			}
			if (autoScan) {
				port = findFreePort("", port);
			}
			listens->insert(new MaListen("", port));

		} else {
			if (autoScan) {
				port = findFreePort(ipAddr, MA_SERVER_DEFAULT_PORT_NUM);
			}
			listens->insert(new MaListen(ipAddr, port));
		}
	}
	mprFree(ipAddr);
	ipAddr = 0;

	host = server->newHost(docRootPath);
	if (host == 0) {
		return MPR_ERR_CANT_OPEN;
	}

	//
	//	Add the default server listening addresses to the HostAddress hash.
	//	FUTURE -- this should be moved into newHost
	//
	hostAddresses = server->getHostAddresses();
	lp = (MaListen*) listens->getFirst();
	while (lp) {
		mprSprintf(addrBuf, sizeof(addrBuf), "%s:%d", lp->getIpAddr(), 
			lp->getPort());
		address = (MaHostAddress*) hostAddresses->lookup(addrBuf);
		if (address == 0) {
			address = new MaHostAddress(addrBuf);
			hostAddresses->insert(address);
		}
		mprLog(MPR_CONFIG, "Listening for HTTP on %s\n", addrBuf);
		address->insertVhost(new MaVhost(host));
		lp = (MaListen*) listens->getNext(lp);
		mprFree(ipAddr);
		ipAddr = mprStrdup(addrBuf);
	}

	//
	//	Setup a module search path that works for production and developement.
	//
#if BLD_FEATURE_DLL
	char	searchPath[MPR_MAX_FNAME];
	mprSprintf(searchPath, sizeof(searchPath), 
			"./lib ../lib ../lib/modules ../../lib ../../lib/modules %s/lib", BLD_PREFIX);
	host->setModuleDirs(searchPath);
#endif

	//
	//	Load all possible modules
	//
#if BLD_FEATURE_AUTH_MODULE
	//
	//	Handler must be added first to authorize all requests.
	//
	if (server->loadModule("auth") == 0) {
		host->addHandler("authHandler", "");
	}
#endif
#if BLD_FEATURE_UPLOAD_MODULE
	//
	//	Must be after auth and before ESP, EGI.
	//
	if (server->loadModule("upload") == 0) {
		host->addHandler("uploadHandler", "");
	}
#endif
#if BLD_FEATURE_CGI_MODULE
	if (server->loadModule("cgi") == 0) {
		host->addHandler("cgiHandler", ".cgi .cgi-nph .bat .cmd .pl .py");
	}
#endif
#if BLD_FEATURE_EGI_MODULE
	if (server->loadModule("egi") == 0) {
		host->addHandler("egiHandler", ".egi");
	}
#endif
#if BLD_FEATURE_ESP_MODULE
	if (server->loadModule("esp") == 0) {
		host->addHandler("espHandler", ".esp .asp");
	}
#endif
#if BLD_FEATURE_C_API_MODULE
	server->loadModule("capi");
#endif
#if BLD_FEATURE_GACOMPAT_MODULE
	server->loadModule("compat");
#endif
#if BLD_FEATURE_SSL_MODULE
	server->loadModule("ssl");
#endif
	//
	//	Only load one of matrixSsl / openssl
	//
#if BLD_FEATURE_OPENSSL_MODULE
	server->loadModule("openSsl");
#elif BLD_FEATURE_MATRIXSSL_MODULE
	server->loadModule("matrixSsl");
#endif
#if BLD_FEATURE_PHP5_MODULE
	if (server->loadModule("php5") == 0) {
		host->addHandler("php5Handler", ".php");
	}
#endif
#if BLD_FEATURE_COPY_MODULE
	//
	//	Handler must be added last to be the catch all
	//
	if (server->loadModule("copy") == 0) {
		host->addHandler("copyHandler", "");
	}
#endif

	//
	//	Create the top level directory
	//
	dir = new MaDir(host);
	dir->setPath(docRootPath);
	host->insertDir(dir);

	//
	//	Add cgi-bin
	//
	mprSprintf(pathBuf, sizeof(pathBuf), "%s/cgi-bin", serverRoot);
	ap = new MaAlias("/cgi-bin/", pathBuf);
	mprLog(4, "ScriptAlias \"/cgi-bin/\":\n\t\t\t\"%s\"\n", pathBuf);
	host->insertAlias(ap);
	loc = new MaLocation(dir->getAuth());
	loc->setPrefix("/cgi-bin/");
	loc->setHandler("cgiHandler");
	host->insertLocation(loc);

	mprFree(docRootPath);
	return 0;
}
예제 #11
0
MaClient::MaClient()
{
	authCnonce = 0;
	authNc = 0;
	serverAlgorithm = 0;
	serverDomain = 0;
	serverNonce = 0;
	serverOpaque = 0;
	serverRealm = 0;
	serverQop = 0;
	serverStale = 0;
	serverAuthType = 0;
	callbackArg = 0;
	callback = 0;
	contentLength = 0;
	contentRemaining = -1;
	currentHost = 0;
	currentPort = -1;
	defaultHost = 0;
	defaultPort = -1;
	errorMsg = 0;
	flags = 0;
	fd = -1;

	inBuf = new MprBuf(MPR_HTTP_CLIENT_BUFSIZE + 1, -1);
	headerValues = 0;

	method = 0;
	outBuf = new MprBuf(MPR_HTTP_CLIENT_BUFSIZE, MPR_HTTP_CLIENT_BUFSIZE);
	password = 0;
	proxyHost = 0;
	proxyPort = -1;
	realm = 0;
	retries = MPR_HTTP_CLIENT_RETRIES;
	responseCode = -1;
	responseProto = 0;
	responseContent = new MprBuf(MPR_HTTP_CLIENT_BUFSIZE, -1);
	responseHeader = new MprBuf(MPR_HTTP_CLIENT_BUFSIZE, MPR_HTTP_MAX_HEADER);
	responseText = 0;
	secret = 0;
	sock = 0;
	state = MPR_HTTP_CLIENT_START;
	timeoutPeriod = MPR_HTTP_CLIENT_TIMEOUT;
	timer = 0;
	timestamp = 0;
	user = 0;
	userFlags = MPR_HTTP_KEEP_ALIVE;
	userHeaders = 0;

#if BLD_FEATURE_LOG
	tMod = new MprLogModule("client");
#endif

#if BLD_FEATURE_MULTITHREAD
	completeCond = new MprCond();
	mutex = new MprMutex();
#endif

#if BLD_FEATURE_MULTITHREAD
	//	FUTURE -- ideal case for spin-locks
	mprGetMpr()->lock();
#endif
	clients.insert(this);
#if BLD_FEATURE_MULTITHREAD
	mprGetMpr()->unlock();
#endif
}
예제 #12
0
MaClient::~MaClient()
{
	//
	//	Must be careful because readEventWrapper is passed "this" and must
	//	not accessed a deleted object. Remove from the list of clients safely
	//	and readEventWrapper will check if it has been deleted.
	//
	mprGetMpr()->lock();
	lock();
	mprGetMpr()->unlock();

	clients.remove(this);

	if (sock) {
		sock->setCallback(readEventWrapper, (void*) this, 0, 0);
		mprLog(3, tMod, "%d: ~MaClient: close sock\n", sock->getFd());
		sock->close(0);
		sock->dispose();
		sock = 0;
	}

	delete headerValues;
	delete inBuf;
	delete outBuf;
	delete responseContent;
	delete responseHeader;

	mprFree(authCnonce);
	mprFree(method);
	mprFree(serverAlgorithm);
	mprFree(serverDomain);
	mprFree(serverNonce);
	mprFree(serverOpaque);
	mprFree(serverRealm);
	mprFree(serverQop);
	mprFree(serverStale);
	mprFree(serverAuthType);
	mprFree(errorMsg);
	mprFree(defaultHost);
	mprFree(proxyHost);
	mprFree(realm);
	mprFree(responseProto);
	mprFree(responseText);
	mprFree(password);
	mprFree(user);
	mprFree(userHeaders);
	mprFree(secret);

	if (timer) {
		timer->stop(MPR_TIMEOUT_STOP);
		timer->dispose();
		timer = 0;
	}

#if BLD_FEATURE_LOG
	delete tMod;
#endif
#if BLD_FEATURE_MULTITHREAD
	delete completeCond;
	delete mutex;
#endif
}