xtacacsd.c
来自「RADIUS协议的认证计费服务」· C语言 代码 · 共 1,593 行 · 第 1/3 页
C
1,593 行
} }#else /* VMS */ if (pw_verify (name, passwd, &pw)) { tp->oresponse = TA_A_ACCEPTED; tp->oreason = TA_A_NONE; /* * Now check the expiration time. */ expired = check_expiration (pw->pw_shell); if (expired == 2) { tp->oresponse = TA_A_DENIED; tp->oreason = TA_A_EXPIRING; } else if (expired == 1) tp->oreason = TA_A_EXPIRING; }#endif /* VMS */o_ok: if (logging) {#ifdef VMS syslog (LOG_INFO, "login query for %s@%s %s\n", name, (char *) inet_ntoa (from.sin_addr), tp->oresponse == TA_A_ACCEPTED ? "accepted" : "rejected");#else /* VMS */ if (pw != NULL) syslog (LOG_INFO, "login query for %s (%s) %s\n", name, pw->pw_gecos, tp->oresponse == TA_A_ACCEPTED ? "accepted" : "rejected"); else syslog (LOG_INFO, "login query for %s %s\n", name, tp->oresponse == TA_A_ACCEPTED ? "accepted" : "rejected");#endif /* VMS */ } tp->type = TA_ANSWER; if (sendto (s, buf, sizeof (tacacstype), 0, client, sizeof (struct sockaddr_in)) != sizeof (tacacstype)) syslog (LOG_ERR, "write: %m\n");#ifndef SYSV free (name); free (passwd);#endif#ifdef DEBUG fprintf (stderr, "process: done\r\n");#endif}/* * new_process * Perform necessary stuff to do a query operation. Return ANSWER. */new_process (s, client, buf)int s;struct sockaddr_in *client;newxtacacstype *buf;{#ifdef DEBUG fprintf (stderr, "new_process: start\r\n");#endif querytime = time (NULL); switch (buf->tp.type) { case XTA_SLIPADDR: case XTA_LOGIN: xlogin (s, client, buf); break; case XTA_CONNECT: xconnect (s, client, buf->tp); break; case XTA_ENABLE: xenable (s, client, buf->tp); break; case XTA_LOGOUT: xlogout (s, client, buf->tp); break; case XTA_RELOAD: xreload (s, client, buf->tp); break; case XTA_SLIPON: xslipon (s, client, buf->tp); break; case XTA_SLIPOFF: xslipoff (s, client, buf->tp); break; default: if (logging) syslog (LOG_INFO, "illegal type specified: %d\n", buf->tp.type); }}#ifndef VMScheck_expiration (date)char *date;{ long day, month, year, leaps, now, expiration, warning; char monthstr[10]; /* * If no date or a shell, let it pass. (Backward compatability.) */ if (!date || (strlen (date) == 0) || (*date == '/')) return (0); /* * Parse date string. Fail it upon error. */ if (sscanf (date, "%s %d %d", monthstr, &day, &year) != 3) return (2); /* * Compute the expiration date in days. */ for (month = 0; month < 12; month++) if (strncmp (monthstr, monthname[month], 3) == 0) break; if (month > 11) return (2); leaps = (year - 1969) / 4 + (((year % 4) == 0) && (month > 2)); expiration = (((year - 1970) * 365) + days_ere_month[month] + (day - 1) + leaps); warning = expiration - WARNING_PERIOD; /* * Get the current time (to the day) */ now = querytime / SEC_IN_DAY; if (now > expiration) return (2); if (now > warning) return (1); return (0);}#endif /* VMS */#ifndef BSD43#ifndef VMS/* * setpwfile * Hack to get around the default for the pw routines using /etc/passwd */#include <sys/stat.h>setpwfile (file)char *file;{ FILE *f; struct stat pwbuf, fbuf; int i; char *c; if (stat ("/etc/passwd", &pwbuf) < 0) { syslog (LOG_ERR, "stat: %m\n"); exit (1); } setpwent (); /* open /etc/passwd */ /* * This loop assumes that the stdio file buffers are contiguous which * isn't true for 4.3, but then we won't be here. */ for (f = stderr + 1; f < stdin + getdtablesize (); f++) if (f->_flag & (_IOREAD | _IOWRT | _IORW) && fstat (fileno (f), &fbuf) >= 0 && pwbuf.st_dev == fbuf.st_dev && pwbuf.st_ino == fbuf.st_ino) { freopen (file, "r", f); fprintf (stderr, "hit at %d\n", fileno (f)); return; } syslog (LOG_ERR, "couldn't find /etc/passwd to replace\n"); exit (1);}#endif /* VMS */#endif#ifdef SYSVgetdtablesize (){ return (_NFILE);}#endifwtmp_entry (line, name, host)char *line, *name, *host;{#ifdef VMS return; /* No WTMP file support yet */#else /* VMS */ struct utmp entry; if (wtmpf == NULL) return; bzero (&entry, sizeof entry); if (strlen (line) < sizeof entry.ut_line) strcpy (entry.ut_line, line); else bcopy (line, entry.ut_line, sizeof entry.ut_line); if (strlen (name) < sizeof entry.ut_name) strcpy (entry.ut_name, name); else bcopy (name, entry.ut_name, sizeof entry.ut_name); if (strlen (host) < sizeof entry.ut_host) strcpy (entry.ut_host, host); else bcopy (host, entry.ut_host, sizeof entry.ut_host); entry.ut_time = querytime; if (fwrite (&entry, sizeof entry, 1, wtmpf) != 1) { if (logging) syslog (LOG_ERR, "couldn't write syslog file\n"); } else fflush (wtmpf);#ifdef DEBUG1 fprintf (stderr, "\nwtmp: %s, %s %s %d", line, name, host, querytime);#endif#endif /* VMS */}xlogin (s, client, buf)int s;struct sockaddr_in *client;register newxtacacstype *buf;{#ifdef SYSV char name[SOME_ARBITRARILY_LARGE_NUMBER]; char passwd[SOME_ARBITRARILY_LARGE_NUMBER];#else char *name, *passwd, *secret, *filename; char *vector, *buffer_ptr; uchar buffer[BUFSIZ]; uchar digest[32];#endif#ifdef VMS int pw, i;#else /* VMS */ struct passwd *pw;#endif /* VMS */ int expired; char linename[20];#ifdef DEBUG fprintf (stderr, "xlogin: starting\r\n"); fprintf (stderr, "xlogin: namelen %d, pwdlen %d\r\n", buf->tp.namelen, buf->tp.pwlen);#endif#ifndef SYSV name = (char *) malloc (buf->tp.namelen + 1); if (name == NULL) perror ("Malloc"); passwd = (char *) malloc (buf->tp.pwlen + 1); if (passwd == NULL) perror ("Malloc"); secret = (char *) malloc (40); if (secret == NULL) perror ("Malloc"); if (name == NULL || passwd == NULL) return;#endif /* not SYSV *//* strncpy(name, ((char *)tp)+XTACACSSIZE, tp->namelen); */ strncpy (name, buf->data, buf->tp.namelen);/* name[tp->namelen] = '\0'; */ name[buf->tp.namelen] = '\0';/* strncpy(passwd, ((char *)tp)+XTACACSSIZE + tp->namelen + 1, tp->pwlen-1); */ strncpy (passwd, &(buf->data[buf->tp.namelen + 1]), buf->tp.pwlen - 1);/* if (tp->pwlen > PASSWD_LENGTH) tp->pwlen = PASSWD_LENGTH; passwd[tp->pwlen] = '\0';*/ if (buf->tp.pwlen > PASSWD_LENGTH) buf->tp.pwlen = PASSWD_LENGTH; passwd[buf->tp.pwlen] = '\0';/* 16 uchar random vector to be appended to the secret *//* vector = (char *) ((char *) tp + sizeof(*tp) + (u_long) tp->namelen + (u_long) tp->pwlen);*/ vector = &(buf->data[buf->tp.namelen + buf->tp.pwlen]); if (get_secret (secret) < 0) { fprintf (stderr, "Access Denied"); return; } strcpy (buffer, secret); buffer_ptr = (char *) (buffer + (u_long) strlen (secret)); memcpy (buffer_ptr, vector, VECTOR_LEN); md5_calc (digest, buffer, strlen (secret) + VECTOR_LEN); for (i = 0; i < strlen (secret); i++) passwd[i] ^= digest[i];#ifdef DEBUG/* fprintf(stderr, "packet: %s %s\r\n", (char *)(tp + 1), (char *)(tp + 1) + tp->namelen); fprintf(stderr, "local: %s %s\r\n", name, passwd);*/#endif#ifdef DEBUG1 fprintf (stderr, "\nxlogin: user %s on tty%x, host %s", name, buf->tp.lport, SenderHost);#endif /* * Assume failure */ buf->tp.response = TA_A_REJECTED; buf->tp.reason = TA_A_DENIED;/* HUJI - check whether the user is in our local database */ { char phone[256], flags; if (get_user_entry (name, passwd, &flags, phone)) { /* got it ok */ if (flags & F_DIALBACK) { /* Need a dialback */ syslog (LOG_INFO, "Dialback requested by '%s' to phone %s\n", name, phone); buf->tp.reason = TA_A_EXPIRING; /* Reject with expired * message */ } else { /* OK - let him in */ syslog (LOG_INFO, "User '%s' passed-in according to NUI file\n", name); buf->tp.response = TA_A_ACCEPTED; buf->tp.reason = TA_A_NONE; } goto n_ok; /* jump over the regular * authorization */ } }/* HUJI - If there is @ or % then remove it and check the address. If it is ours - continue as usual. If not, and if the other machine is listed in the ones we trust - ask it */ { char *p; p = strchr (name, '@'); if (p == NULL) p = strchr (name, '%'); if (p != NULL) { *p++ = '\0'; /* Remove the @ from the username */ upcase_string (p); if (strcmp (p, LOCAL_INTERNET_NAME) != 0) { /* Not us */ verify_user_remote (p, name, passwd); goto RemoteVerified; } } }/* HUJI - end of modifications */#ifdef VMS if (check_username (name, filename) == 1) { if ((verify_user (name, passwd, &pw) & 0x1) == 1) { /* Verify returned ok */ if (pw == USER_OK) { buf->tp.response = TA_A_ACCEPTED; buf->tp.reason = TA_A_NONE; } else if (pw == USER_EXPIRING) { buf->tp.response = TA_A_ACCEPTED; buf->tp.reason = TA_A_EXPIRING; } else if (pw == USER_EXPIRED) { buf->tp.response = TA_A_DENIED; buf->tp.reason = TA_A_EXPIRING; } } }#else /* VMS */ if (pw_verify (name, passwd, &pw)) { buf->tp.response = XTA_A_ACCEPTED; buf->tp.reason = XTA_A_NONE; buf->tp.uuid = pw->pw_uid; buf->tp.accesslist = pw->pw_gid; buf->tp.flags = xta_getflags (pw->pw_gecos); /* * Now check the expiration time. */ expired = check_expiration (pw->pw_shell); if (expired == 2) { buf->tp.response = TA_A_DENIED; buf->tp.reason = TA_A_EXPIRING; } else if (expired == 1) buf->tp.reason = TA_A_EXPIRING; }#endif /* VMS */n_ok:RemoteVerified: sprintf (linename, "TTY%x", buf->tp.lport); if (buf->tp.response == TA_A_ACCEPTED && buf->tp.type == XTA_LOGIN) wtmp_entry (linename, name, SenderHost); if (logging && buf->tp.type == XTA_LOGIN) {#ifdef VMS syslog (LOG_INFO, "xlogin query from %s %s for %s %s\n", SenderHost, linename, name, buf->tp.response == TA_A_ACCEPTED ? "accepted" : "rejected");#else /* VMS */ if (pw != NULL) syslog (LOG_INFO, "xlogin query from %s %s for %s (%s) %s\n", SenderHost, linename, name, pw->pw_gecos, buf->tp.response == TA_A_ACCEPTED ? "accepted" : "rejected"); else syslog (LOG_INFO, "xlogin query from %s %s for %s %s\n", SenderHost, linename, name, buf->tp.response == TA_A_ACCEPTED ? "accepted" : "rejected");#endif /* VMS */ } if (logging && buf->tp.type == XTA_SLIPADDR) {#ifdef VMS syslog (LOG_INFO, "slipaddress from %s %s for %s %s\n", SenderHost, linename, name, buf->tp.response == TA_A_ACCEPTED ? "accepted" : "rejected");#else /* VMS */ if (pw != NULL) syslog (LOG_INFO, "slipaddress from %s %s for %s (%s) %s\n", SenderHost, linename, name, pw->pw_gecos, buf->tp.response == TA_A_ACCEPTED ? "accepted" : "rejected"); else syslog (LOG_INFO, "slipaddress from %s %s for %s %s\n", SenderHost, linename, name, buf->tp.response == TA_A_ACCEPTED ? "accepted" : "rejected");#endif } buf->tp.type = TA_ANSWER; /* We want to copy the current data stored in tp to buffer */ /* * we want to copy the vector we received from the sender to the end * of the packet we want to send to md5 */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?