Пример #1
0
static void server_job_signal(int sig ATTRIBUTE_UNUSED)
{
	snd_pcm_direct_semaphore_down(server_job_dmix, DIRECT_IPC_SEM_CLIENT);
	server_cleanup(server_job_dmix);
	server_printf("DIRECT SERVER EXIT - SIGNAL\n");
	_exit(EXIT_SUCCESS);
}
Пример #2
0
static void server_job(snd_pcm_direct_t *dmix)
{
	int ret, sck, i;
	int max = 128, current = 0;
	struct pollfd pfds[max + 1];

	server_job_dmix = dmix;
	/* don't allow to be killed */
	signal(SIGHUP, server_job_signal);
	signal(SIGQUIT, server_job_signal);
	signal(SIGTERM, server_job_signal);
	signal(SIGKILL, server_job_signal);
	/* close all files to free resources */
	i = sysconf(_SC_OPEN_MAX);
#ifdef SERVER_JOB_DEBUG
	while (--i >= 3) {
#else
	while (--i >= 0) {
#endif
		if (i != dmix->server_fd && i != dmix->hw_fd)
			close(i);
	}
	
	/* detach from parent */
	setsid();

	pfds[0].fd = dmix->server_fd;
	pfds[0].events = POLLIN | POLLERR | POLLHUP;

	server_printf("DIRECT SERVER STARTED\n");
	while (1) {
		ret = poll(pfds, current + 1, 500);
		server_printf("DIRECT SERVER: poll ret = %i, revents[0] = 0x%x, errno = %i\n", ret, pfds[0].revents, errno);
		if (ret < 0) {
			if (errno == EINTR)
				continue;
			/* some error */
			break;
		}
		if (ret == 0 || (pfds[0].revents & (POLLERR | POLLHUP))) {	/* timeout or error? */
			struct shmid_ds buf;
			snd_pcm_direct_semaphore_down(dmix, DIRECT_IPC_SEM_CLIENT);
			if (shmctl(dmix->shmid, IPC_STAT, &buf) < 0) {
				_snd_pcm_direct_shm_discard(dmix);
				snd_pcm_direct_semaphore_up(dmix, DIRECT_IPC_SEM_CLIENT);
				continue;
			}
			server_printf("DIRECT SERVER: nattch = %i\n", (int)buf.shm_nattch);
			if (buf.shm_nattch == 1)	/* server is the last user, exit */
				break;
			snd_pcm_direct_semaphore_up(dmix, DIRECT_IPC_SEM_CLIENT);
			continue;
		}
		if (pfds[0].revents & POLLIN) {
			ret--;
			sck = accept(dmix->server_fd, 0, 0);
			if (sck >= 0) {
				server_printf("DIRECT SERVER: new connection %i\n", sck);
				if (current == max) {
					close(sck);
				} else {
					unsigned char buf = 'A';
					pfds[current+1].fd = sck;
					pfds[current+1].events = POLLIN | POLLERR | POLLHUP;
					_snd_send_fd(sck, &buf, 1, dmix->hw_fd);
					server_printf("DIRECT SERVER: fd sent ok\n");
					current++;
				}
			}
		}
		for (i = 0; i < current && ret > 0; i++) {
			struct pollfd *pfd = &pfds[i+1];
			unsigned char cmd;
			server_printf("client %i revents = 0x%x\n", pfd->fd, pfd->revents);
			if (pfd->revents & (POLLERR | POLLHUP)) {
				ret--;
				close(pfd->fd);
				pfd->fd = -1;
				continue;
			}
			if (!(pfd->revents & POLLIN))
				continue;
			ret--;
			if (read(pfd->fd, &cmd, 1) == 1)
				cmd = 0 /*process command */;
		}
		for (i = 0; i < current; i++) {
			if (pfds[i+1].fd < 0) {
				if (i + 1 != max)
					memcpy(&pfds[i+1], &pfds[i+2], sizeof(struct pollfd) * (max - i - 1));
				current--;
			}
		}
	}
	server_cleanup(dmix);
	server_printf("DIRECT SERVER EXIT\n");
#ifdef SERVER_JOB_DEBUG
	close(0); close(1); close(2);
#endif
	_exit(EXIT_SUCCESS);
}

int snd_pcm_direct_server_create(snd_pcm_direct_t *dmix)
{
	int ret;

	dmix->server_fd = -1;

	ret = get_tmp_name(dmix->shmptr->socket_name, sizeof(dmix->shmptr->socket_name));
	if (ret < 0)
		return ret;
	
	ret = make_local_socket(dmix->shmptr->socket_name, 1, dmix->ipc_perm, dmix->ipc_gid);
	if (ret < 0)
		return ret;
	dmix->server_fd = ret;

	ret = listen(dmix->server_fd, 4);
	if (ret < 0) {
		close(dmix->server_fd);
		return ret;
	}
	
	ret = fork();
	if (ret < 0) {
		close(dmix->server_fd);
		return ret;
	} else if (ret == 0) {
		ret = fork();
		if (ret == 0)
			server_job(dmix);
		_exit(EXIT_SUCCESS);
	} else {
		waitpid(ret, NULL, 0);
	}
	dmix->server_pid = ret;
	dmix->server = 1;
	return 0;
}
Пример #3
0
int sserver_auth_protocol_connect(const struct protocol_interface *protocol, const char *auth_string)
{
	CScramble scramble;
	char *tmp;
	int certonly;
	char *client_version = NULL;
	char keyfile[256];
	const char *hostname = NULL;

    if (!strcmp (auth_string, "BEGIN SSL VERIFICATION REQUEST"))
		sserver_protocol_interface.verify_only = 1;
    else if (!strcmp (auth_string, "BEGIN SSL AUTH REQUEST"))
		sserver_protocol_interface.verify_only = 0;
	else
		return CVSPROTO_NOTME;

	write(current_server()->out_fd,SSERVER_INIT_STRING,sizeof(SSERVER_INIT_STRING)-1);

	if(!CGlobalSettings::GetGlobalValue("cvsnt","PServer","CertificatesOnly",keyfile,sizeof(keyfile)))
		certonly = atoi(keyfile);
	if(!CGlobalSettings::GetGlobalValue("cvsnt","PServer","ServerDnsName",keyfile,sizeof(keyfile)))
		hostname = keyfile;

	if(!ServerAuthenticate(hostname))
		return CVSPROTO_AUTHFAIL;

	QueryContextAttributes(&contextHandle,SECPKG_ATTR_STREAM_SIZES,&secSizes);

	g_sslBufferInPos=g_sslBufferOutPos=0;
	g_sslBufferInLen=g_sslBufferOutLen=0;

    set_encrypted_channel(1); /* Error must go through us now */

	PCERT_CONTEXT sc;
	PCCERT_CHAIN_CONTEXT pcc;
	CERT_SIMPLE_CHAIN  *psc;
	CERT_CHAIN_PARA para = { sizeof(CERT_CHAIN_PARA) };
	DWORD trust,rc;
	BOOL cert = FALSE;
	
	rc = QueryContextAttributes(&contextHandle,SECPKG_ATTR_REMOTE_CERT_CONTEXT,&sc);
	if(rc && rc!=SEC_E_NO_CREDENTIALS)
		server_error(1,"Couldn't get client certificate");

	if(rc!=SEC_E_NO_CREDENTIALS) /* The client doesn't have to send us a cert. as cvs uses passwords normally */
	{
		if(!CertGetCertificateChain(NULL, sc, NULL, NULL, &para, 0, NULL, &pcc))
			server_error(1,"Couldn't get client certificate chain");

		psc = pcc->rgpChain[0];
		trust = psc->TrustStatus.dwErrorStatus;
	 
		if (trust)
		{
			if (trust & (CERT_TRUST_IS_PARTIAL_CHAIN | CERT_TRUST_IS_UNTRUSTED_ROOT))
				server_error(1,"Client sent self signed certificate");
			else if (trust & (CERT_TRUST_IS_NOT_TIME_VALID))
				server_error(1,"Client certificate expired");
			else
				server_error(1,"Client certificate verification failed - %08x",trust);
		}

		CertFreeCertificateChain(pcc);
		FreeContextBuffer(sc);

		cert = TRUE;
	}
 
    /* Get the three important pieces of information in order. */
    /* See above comment about error handling.  */

	/* get version, if sent.  1.0 clients didn't have this handshake so we have to handle that. */
	server_getline (protocol, &client_version, MAX_PATH);
	if(strncmp(client_version,"SSERVER-CLIENT ",15))
	{
		sserver_protocol_interface.auth_repository = client_version;
		client_version = NULL;
	}
	else
    	server_getline (protocol, &sserver_protocol_interface.auth_repository, MAX_PATH);
    server_getline (protocol, &sserver_protocol_interface.auth_username, MAX_PATH);
	server_getline (protocol, &sserver_protocol_interface.auth_password, MAX_PATH);

	if(client_version) free(client_version);
	client_version = NULL;

    /* ... and make sure the protocol ends on the right foot. */
    /* See above comment about error handling.  */
    server_getline(protocol, &tmp, MAX_PATH);
    if (strcmp (tmp,
		sserver_protocol_interface.verify_only ?
		"END SSL VERIFICATION REQUEST" : "END SSL AUTH REQUEST")
	!= 0)
    {
		server_printf ("bad auth protocol end: %s\n", tmp);
		free(tmp);
		return CVSPROTO_FAIL;
    }

	strcpy(sserver_protocol_interface.auth_password, scramble.Unscramble(sserver_protocol_interface.auth_password));

	free(tmp);

	switch(certonly)
	{
	case 0:
		break;
	case 1:
		if(!cert)
		{
			server_error(0,"E Login requires a valid client certificate.\n");
			return CVSPROTO_AUTHFAIL;
		}
		free(sserver_protocol_interface.auth_password);
		sserver_protocol_interface.auth_password = NULL;
		break;
	case 2:
		if(!cert)
		{
			server_error(0,"E Login requires a valid client certificate.\n");
			return CVSPROTO_AUTHFAIL;
		}
		break;
	};

	return CVSPROTO_SUCCESS;
}
Пример #4
0
int sspi_auth_protocol_connect(const struct protocol_interface *protocol, const char *auth_string)
{
        char *protocols;
        const char *proto;
	int fdin, fdout, fderr;
	int l;
	short len;
	char line[1024];
	char buf[1024];
	int first;

	if (!strcmp (auth_string, "BEGIN SSPI"))
           sspi_protocol_interface.verify_only = 0;
        else
           return CVSPROTO_NOTME;

        server_getline(protocol, &protocols, 1024);

        if(!protocols)
        {
                server_printf("Nope!\n");
                return CVSPROTO_FAIL;
        }
        else if(strstr(protocols,"Negotiate"))
                proto="Negotiate";
        else if(strstr(protocols,"NTLM"))
                proto="NTLM";
        else
        {
                server_printf("Nope!\n");
                return CVSPROTO_FAIL;
        }
        free(protocols);

        server_printf("%s\n",proto); /* We have negotiated NTLM */

	if(run_command(winbindwrapper, &fdin, &fdout, &fderr))
	  return CVSPROTO_FAIL;

        first=1;	
	do
	{
	read(current_server()->in_fd,&len,2);
	len=ntohs(len);
	l=read(current_server()->in_fd,buf,len);
	if(l<0)
	  return CVSPROTO_FAIL;
	if(first)
	  	strcpy(line,"YR ");
	else
		strcpy(line,"KK ");
	first = 0;
	l=base64enc((unsigned char *)buf,(unsigned char *)line+3,len);
	strcat(line,"\n");
	write(fdin, line, strlen(line));
	l=read(fdout, line, sizeof(line));
	if(l<0)
	  return CVSPROTO_FAIL;
	line[l]='\0';
	if(line[0]=='T' && line[1]=='T')
	{
	  len=base64dec((unsigned char *)line+3,(unsigned char *)buf,l-4);
	  base64enc((unsigned char *)buf,(unsigned char *)line+3,len);
	  len=htons(len);
	  write(current_server()->out_fd,&len,2);
	  write(current_server()->out_fd,buf,ntohs(len));
	}
	} while(line[0]=='T' && line[1]=='T');
	if(line[0]!='A' || line[1]!='F')
	   return CVSPROTO_FAIL;
	close(fdin);
	close(fdout);
	close(fderr);

	line[strlen(line)-1]='\0';
        sspi_protocol_interface.auth_username = strdup(line+3);

        /* Get the repository details for checking */
        server_getline (protocol, &sspi_protocol_interface.auth_repository, 4096);
        return CVSPROTO_SUCCESS;
}