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 + -
显示快捷键?