xtacacsd.c

来自「RADIUS协议的认证计费服务」· C语言 代码 · 共 1,593 行 · 第 1/3 页

C
1,593
字号
	memcpy (buf->data, vector, VECTOR_LEN);	/* we want to copy the secret after the vector */	memcpy (&(buf->data[VECTOR_LEN]), secret, strlen (secret));	/*	 * send this entire new buf to md5_calc so we can get a digest to	 * append at tp->access back to the sending program	 */	md5_calc (digest, buf, sizeof (xtacacstype) + VECTOR_LEN + strlen (secret));	/* copy the digest after the accesslist */	memcpy (buf->data, digest, VECTOR_LEN);	if ((i = (sendto (s, buf, sizeof (xtacacstype) + VECTOR_LEN, 0, client,	sizeof (struct sockaddr_in)))) != sizeof (xtacacstype) + VECTOR_LEN)	{		syslog (LOG_ERR, "write: %m\n");		printf ("i=%d", i);	}#ifndef SYSV	free (name);	free (passwd);#endif#ifdef DEBUG	fprintf (stderr, "xlogin: done\r\n");#endif}xconnect (s, client, tp)int             s;struct sockaddr_in *client;xtacacstype    *tp;{	struct hostent *hp1;	char           *name = ((char *) tp) + XTACACSSIZE;	name[tp->namelen] = 0;	hp1 = gethostbyaddr (&tp->dhost, sizeof (struct in_addr), AF_INET);#ifdef DEBUG1	fprintf (stderr, "\nxconnect: user %.*s(%d) to %s:%d", tp->namelen,		 ((char *) tp) + XTACACSSIZE, tp->uuid,	     hp1 ? hp1->h_name : (char *) inet_ntoa (tp->dhost), tp->dport);#endif	if (logging)		syslog (LOG_INFO, "xconnect from %s tty%x for %s (%d) to %s:%d\n",			SenderHost,			tp->lport, name, tp->uuid,			hp1 ? hp1->h_name : (char *) inet_ntoa (tp->dhost), tp->dport);	replyok (s, client, tp);}xenable (s, client, tp)int             s;struct sockaddr_in *client;xtacacstype    *tp;{#ifdef SYSV	char            name[SOME_ARBITRARILY_LARGE_NUMBER];	char            passwd[SOME_ARBITRARILY_LARGE_NUMBER];#else	char           *name,	               *passwd;#endif	struct passwd  *pw;	int             expired;	char            linename[20];#ifndef SYSV	name = (char *) malloc (tp->namelen + 1);	passwd = (char *) malloc (tp->pwlen + 1);	if (name == NULL || passwd == NULL)		return;#endif				/* not SYSV */	sprintf (linename, "TTY%x", tp->lport);	strncpy (name, (char *) (tp + 1), tp->namelen);	name[tp->namelen] = '\0';	strncpy (passwd, (char *) (tp + 1) + tp->namelen, tp->pwlen);	if (tp->pwlen > PASSWD_LENGTH)		tp->pwlen = PASSWD_LENGTH;	passwd[tp->pwlen] = '\0';#ifdef DEBUG1	fprintf (stderr, "\nxenable: user %s on tty%x, host %s", name, tp->lport,		 SenderHost);#endif	/*	 * Assume failure	 */	tp->response = TA_A_REJECTED;	tp->reason = TA_A_DENIED;#ifdef VMS	if ((verify_user ("$ENABLE$", passwd, &pw) & 0x1) == 1)	{			/* Verify returned ok */		if (pw == USER_OK)		{			tp->response = TA_A_ACCEPTED;			tp->reason = TA_A_NONE;		}		else if (pw == USER_EXPIRING)		{			tp->response = TA_A_ACCEPTED;			tp->reason = TA_A_EXPIRING;		}		else if (pw == USER_EXPIRED)		{			tp->reason = TA_A_EXPIRING;		}	}#else				/* VMS */	if (pw_verify ("$enable$", passwd, &pw))	{		tp->response = XTA_A_ACCEPTED;		tp->reason = XTA_A_NONE;		tp->uuid = pw->pw_uid;		tp->accesslist = pw->pw_gid;		tp->flags = xta_getflags (pw->pw_gecos);		/*		 * Now check the expiration time.		 */		expired = check_expiration (pw->pw_shell);		if (expired == 2)		{			tp->response = TA_A_DENIED;			tp->reason = TA_A_EXPIRING;		}		else if (expired == 1)			tp->reason = TA_A_EXPIRING;	}#endif				/* VMS */	sprintf (linename, "TTY%x", tp->lport);	tp->type = TA_ANSWER;	if (logging)		syslog (LOG_INFO, "xenable from %s %s for %s %s\n",			SenderHost,			linename, name,		   tp->response == TA_A_ACCEPTED ? "accepted" : "rejected");	if (sendto (s, buf, XTACACSSIZE, 0, client,		    sizeof (struct sockaddr_in)) != XTACACSSIZE)		syslog (LOG_ERR, "write: %m\n");#ifndef SYSV	free (name);	free (passwd);#endif}xlogout (s, client, tp)int             s;struct sockaddr_in *client;xtacacstype    *tp;{	char           *name = ((char *) tp) + XTACACSSIZE;	char            linename[20];	char           *reason;	switch (tp->reason)	{	    case XTA_R_IDLE:		reason = "Idle-timeout";		break;	    case XTA_R_DROP:		reason = "Carrier-Drop";		break;	    case XTA_R_BAD:		reason = "Bad-Passwords";		break;	    case XTA_R_QUIT:		reason = "";		break;	    default:		reason = "Unknown-reason";		break;	}	name[tp->namelen] = 0;#ifdef DEBUG1	fprintf (stderr, "\nxlogout:  user %s(%d) line %x %s", name, tp->uuid,		 tp->lport, reason);#endif	sprintf (linename, "TTY%x", tp->lport);	if (logging)		syslog (LOG_INFO, "xlogout from %s %s, user %s(%d) %s\n",			SenderHost, linename,			name, tp->uuid, reason);	wtmp_entry (linename, "", SenderHost);	replyok (s, client, tp);}xreload (s, client, tp)int             s;struct sockaddr_in *client;xtacacstype    *tp;{#ifdef DEBUG1	fprintf (stderr, "\nxreload: host %s", SenderHost);#endif	if (logging)		syslog (LOG_INFO, "system reload from %s\n", SenderHost);	wtmp_entry ("~", "", SenderHost);	replyok (s, client, tp);}xslipon (s, client, tp)int             s;struct sockaddr_in *client;xtacacstype    *tp;{	struct hostent *hp1;	char            linename[20];	char           *name = (char *) (tp + 1);	name[tp->namelen] = 0;	hp1 = gethostbyaddr (&tp->dhost, sizeof (struct in_addr), AF_INET);#ifdef DEBUG1	fprintf (stderr, "\nxslipon:  user %.*s(%d) line %x slip address %s",	      tp->namelen, ((char *) tp) + XTACACSSIZE, tp->uuid, tp->lport,		 hp1 ? hp1->h_name : (char *) inet_ntoa (tp->dhost));#endif	sprintf (linename, "SLIP%x", tp->lport);	wtmp_entry (linename, name, hp1 ? hp1->h_name : (char *) inet_ntoa (tp->dhost));	if (logging)		syslog (LOG_INFO, "xslipon from %s %s for  user %s(%d) address %s\n",			SenderHost, linename,			name, tp->uuid,			hp1 ? hp1->h_name : (char *) inet_ntoa (tp->dhost));	replyok (s, client, tp);}xslipoff (s, client, tp)int             s;struct sockaddr_in *client;xtacacstype    *tp;{	struct hostent *hp1;	char            linename[20];	char           *name;	hp1 = gethostbyaddr (&tp->dhost, sizeof (struct in_addr), AF_INET);#ifdef DEBUG1	fprintf (stderr, "\nxslipoff:  user %.*s(%d) line %x slip address %s",	      tp->namelen, ((char *) tp) + XTACACSSIZE, tp->uuid, tp->lport,		 hp1 ? hp1->h_name : (char *) inet_ntoa (tp->dhost));#endif	sprintf (linename, "SLIP%x", tp->lport);	wtmp_entry (linename, "", hp1 ? hp1->h_name : (char *) inet_ntoa (tp->dhost));	name = (char *) (((char *) tp) + XTACACSSIZE);	name[tp->namelen] = 0;	if (logging)		if (logging)			syslog (LOG_INFO, "xslip off from %s %s for %s(%d) address %s\n",				SenderHost, linename,				name, tp->uuid,			hp1 ? hp1->h_name : (char *) inet_ntoa (tp->dhost));	replyok (s, client, tp);}xta_getflags (string)char           *string;{	return (0);}/* * Send an "ok" reply to client (for things like reload, logout) */replyok (s, client, tp)int             s;struct sockaddr_in *client;xtacacstype    *tp;{	tp->response = XTA_A_ACCEPTED;	tp->reason = XTA_A_NONE;	tp->type = TA_ANSWER;	if (sendto (s, buf, XTACACSSIZE, 0, client,		    sizeof (struct sockaddr_in)) != XTACACSSIZE)		syslog (LOG_ERR, "write: %m\n");}/* HUJI | If the user specified @some-host or %host verify that this is a trusted host and | send the query to it. |  Both the input and the output and in BUF. We assume that it was initialized | to an error reply, so in case of errors we do not touch it. */verify_user_remote (host, name, passwd)char           *host,		/* The host name to query */               *name,		/* the username without @ */               *passwd;		/* the password */{	int             i,	                s,	/* Socket channel */	                size;	/* Send size */	xtacacstype    *tp;	struct hostent *hp1;	/* For getting the host address */	struct sockaddr_in RemoteSocket;	fd_set          ReadFds;/* For select */	struct timeval  timeout;	int             TransactionID;	/* The ID the caller gave to this					 * trnasaction */	tp = (struct xtacacstype *) & (buf.tp);/* Check whether the host is in the allowed list */	size = strlen (host);	for (i = 0; *TrustedHosts[i] != '\0'; i++)		if (strncmp (host, TrustedHosts[i], size) == 0)	/* Match */			break;	if (*TrustedHosts[i] == '\0')	/* Not found */		return;/* OK - the host is trusted. Find its IP address. */	if ((hp1 = gethostbyname (TrustedHosts[i])) == NULL)		return;/* Rewrite the username and password so the username now do not contain the @ */	strcpy (((char *) tp) + XTACACSSIZE, name);	tp->namelen = strlen (name);	tp->pwlen = strlen (passwd);	strcpy (((char *) tp) + XTACACSSIZE + tp->namelen, passwd);	size = XTACACSSIZE + tp->namelen + tp->pwlen;	/* Total size */	TransactionID = tp->trans;	/* Save it to compare later *//* Create a local socket */	if ((s = socket (AF_INET, SOCK_DGRAM, 0)) == -1)	{		perror ("Socket");		return;	}/* Fill the Sockaddr parameters */	bzero ((caddr_t) & RemoteSocket, sizeof (RemoteSocket));	memcpy ((char *) &RemoteSocket.sin_addr.s_addr,		(char *) hp1->h_addr, sizeof (RemoteSocket.sin_addr.s_addr));	RemoteSocket.sin_family = hp1->h_addrtype;	RemoteSocket.sin_port = htons (TACACS_PORT);	if (sendto (s, buf, size, 0, &RemoteSocket, sizeof (RemoteSocket)) < size)	{		perror ("Sendto");		close (s);		return;	}/* Now, wait up to the sepcified time to the reply */	timeout.tv_sec = REMOTE_TACACS_TIMEOUT;	timeout.tv_usec = 0;	FD_ZERO (&ReadFds);	FD_SET (s, &ReadFds);	if (select (getdtablesize (), &ReadFds, NULL, NULL, &timeout) <= 0)	{		/* Timeout or error */		close (s);		return;	}/* OK, now read */	size = sizeof (RemoteSocket);	if (recvfrom (s, buf, XTACACSSIZE, 0, &RemoteSocket, &size) < XTACACSSIZE)	{		perror ("Recvfrom");		close (s);		return;	}	close (s);/* Check that the sender is indeed the one we asked and from the port we asked.   If not - invalidate the response. If yes - return as-is */	if ((memcmp ((char *) &RemoteSocket.sin_addr.s_addr,	(char *) hp1->h_addr, sizeof (RemoteSocket.sin_addr.s_addr)) != 0) ||			(RemoteSocket.sin_port != ntohs (TACACS_PORT)))	{		syslog (LOG_INFO, "Received reply from host %x instead of %x\n",			RemoteSocket.sin_addr.s_addr, (int) hp1->h_addr);		tp->response = TA_A_REJECTED;		tp->reason = TA_A_DENIED;	}	if (tp->trans != TransactionID)	{			/* received response for a different query */		syslog (LOG_INFO, "Transaction ID different: %d != %d from host %x\n",		    tp->trans, TransactionID, RemoteSocket.sin_addr.s_addr);		tp->response = TA_A_REJECTED;		tp->reason = TA_A_DENIED;	}}#ifndef VMS/* upcase_string *   Upcase a string in place. */void upcase_string (s)char           *s;{	while (*s)	{		*s = _toupper (*s);		s++;	}}				/* upcase_string */#endif				/* VMS *//* Check_valid username    User names are read from the given file.  The name    of the file is hard coded for the time being but    can be made to pass as an argument when the daemon is started    Arguments: char *name,*filename    Returns:  	     1 -  if the user is not found in the file.             0 -  if the user is found in the file or null username	     -1   if some error occurs*/int check_username (name, filename)char           *name;char           *filename;{	FILE           *fp;	int             done,	                len;	char            username[32];	fp = fopen ("user_list.lis", "r");	if (fp == NULL)	{		syslog (LOG_ERR, "can't open file user_list.lis\n");		return -1;	}	done = 0;	if (strlen (name) == 0)	{		syslog (LOG_INFO, "Null Username found. rejected\n");		return 0;	}	my_lower (name);	while (!done)	{		fscanf (fp, "%s", username);		len = strlen (username);		my_lower (username);		if (strncmp (name, username, len) == 0)		{			syslog (LOG_INFO, "User %s found in file. rejecting\n", name);			return 0;		}		if (feof (fp))			done = 1;		else			fscanf (fp, "\n");	}	fclose (fp);	return 1;}int get_secret (s)char           *s;{	FILE           *fp;	fp = fopen ("secfile.lis", "r");	if (fp == NULL)	{		syslog (LOG_ERR, "can't open file secfile.lis");		return -1;	}	fscanf (fp, "%s", s);	fclose (fp);	return 1;}my_lower (s)char           *s;{	char           *p;	p = s;	while (*s != '\0')	{		*s = toascii (tolower (*s));		s++;	}	s = p;}

⌨️ 快捷键说明

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