📄 pppd-2.2.0g.patch
字号:
+ "invalid reply content, incorrect key?");+ return(system_err_msg);+ }++ /* save status and clean up */+ r=tb->status;+ if(tb->msg_len) {+ msg=(char *) xcalloc(1, tb->msg_len);+ bcopy(tb+TAC_ACCT_REPLY_FIXED_FIELDS_SIZE, msg, tb->msg_len); + } else+ msg="Accounting failed";++ free(tb);++ /* server logged our request successfully */+ if(r == TAC_PLUS_ACCT_STATUS_SUCCESS) {+ TACDEBUG((LOG_DEBUG, "%s: accounted ok", __FUNCTION__))+ return(NULL);+ }+ /* return pointer to server message */+ syslog(LOG_DEBUG, "accounting failed, server reply was %d (%s)", + r, msg);+ return(msg);++}+++/* reads packet from TACACS+ server; returns:+ * NULL if the authentication succeded+ * string pointer if it failed+ */+char *tac_authen_pap_read(int fd) {+ HDR th;+ struct authen_reply *tb;+ int len_from_header, r, len_from_body;+ char *msg = NULL;++ /* read the reply header */+ r=read(fd, &th, TAC_PLUS_HDR_SIZE);+ if(r < TAC_PLUS_HDR_SIZE) {+ syslog(LOG_ERR,+ "error reading PAP authen header, read %d of %d: %m",+ r, TAC_PLUS_HDR_SIZE);+ return(system_err_msg);+ }++ /* check the reply fields in header */+ if(th.type != TAC_PLUS_AUTHEN) {+ syslog(LOG_ERR,+ "unrelated reply, type %d, expected %d", th.type,+ TAC_PLUS_AUTHEN);+ return(protocol_err_msg);+ } else if(th.seq_no != 2) {+ syslog(LOG_ERR, "not a reply - seq_no %d != 2", th.seq_no);+ return(protocol_err_msg);+ } else if(ntohl(th.session_id) != session_id) {+ syslog(LOG_ERR, + "unrelated reply, received session_id %d != sent %d",+ ntohl(th.session_id), session_id);+ return(protocol_err_msg);+ }+ + len_from_header=ntohl(th.datalength);+ tb=(struct authen_reply *) xcalloc(1, len_from_header);++ /* read reply packet body */+ r=read(fd, tb, len_from_header);+ if(r < len_from_header) {+ syslog(LOG_ERR,+ "incomplete message body, %d bytes, expected %d: %m",+ r, len_from_header);+ return(system_err_msg);+ }++ /* decrypt the body */+ _tac_crypt((u_char *) tb, &th, len_from_header);++ /* check the length fields */+ len_from_body=sizeof(tb->status) + sizeof(tb->flags) ++ sizeof(tb->msg_len) + sizeof(tb->data_len) ++ tb->msg_len + tb->data_len;++ if(len_from_header != len_from_body) {+ syslog(LOG_ERR,+ "invalid reply content, incorrect key?");+ return(system_err_msg);+ }++ /* save status and clean up */+ r=tb->status;+ if(tb->msg_len) {+ msg=(char *) xcalloc(1, tb->msg_len);+ bcopy(tb+TAC_AUTHEN_REPLY_FIXED_FIELDS_SIZE, msg, tb->msg_len); + } else+ msg="Login incorrect";++ free(tb);++ /* server authenticated username and password successfully */+ if(r == TAC_PLUS_AUTHEN_STATUS_PASS) {+ TACDEBUG((LOG_DEBUG, "%s: authentication ok", __FUNCTION__))+ return(NULL);+ }+ + /* return pointer to server message */+ syslog(LOG_DEBUG, "authentication failed, server reply was %d (%s)", + r, msg);+ return(msg);++} /* tac_authen_pap_read */++void tac_add_attrib(struct tac_attrib *attr, char *name, char *value) {+ struct tac_attrib *a;+ u_char l1, l2;++ a = attr;++ /* find last block in chain */+ while((a->attr != 0) && (a->next != 0)) {+ a = a->next;+ }+ + /* fill the block */+ l1 = (u_char) strlen(name);+ l2 = (u_char) strlen(value);+ a->attr_len=l1+l2+1;+ a->attr = (char *) xcalloc(1, l1+l2+1);+ bcopy(name, a->attr, l1);+ *(a->attr+l1)='=';+ bcopy(value, (a->attr+l1+1), l2);++ /* allocate next structure */+ a->next=(struct tac_attrib *) xcalloc(1, sizeof(struct tac_attrib));+ +}++void tac_free_attrib(struct tac_attrib *attr) {+ struct tac_attrib *a;+ struct tac_attrib *b;++ a = attr;++ while(a->attr != 0 && a) {+ free(a->attr);+ b = a;+ a = a->next;+ free(b);+ }++}++/* make MD5 pseudo pad for TACACS+ encryption+ use data from packet header and secret, which+ should be a global var */+u_char *_tac_md5_pad(int len, HDR *hdr) {+ int n, i, bufsize;+ int bp=0; /* buffer pointer */+ int pp=0; /* pad pointer */+ u_char *pad;+ u_char *buf;+ MD5_CTX mdcontext;++ /* make pseudo pad */+ n=(int)(len/16)+1; /* number of MD5 runs */+ bufsize=sizeof(hdr->session_id) + strlen(tac_secret) + sizeof(hdr->version)+ + sizeof(hdr->seq_no) + MD5_LEN + 10;+ buf= (u_char *) xcalloc(1, bufsize);+ pad= (u_char *) xcalloc(n, MD5_LEN);++ for(i=0; i<n; i++) {+ /* MD5_1 = MD5{session_id, secret, version, seq_no}+ MD5_2 = MD5{session_id, secret, version, seq_no, MD5_1} */++ /* place session_id, key, version and seq_no in buffer */+ bp=0;+ bcopy(&hdr->session_id, buf, sizeof(session_id));+ bp+=sizeof(session_id);+ bcopy(tac_secret, buf+bp, strlen(tac_secret));+ bp+=strlen(tac_secret);+ bcopy(&hdr->version, buf+bp, sizeof(hdr->version));+ bp+=sizeof(hdr->version);+ bcopy(&hdr->seq_no, buf+bp, sizeof(hdr->seq_no));+ bp+=sizeof(hdr->seq_no);++ /* append previous pad if this is not the first run */+ if(i) {+ bcopy(pad+((i-1)*MD5_LEN), buf+bp, MD5_LEN);+ bp+=MD5_LEN;+ }+ + MD5Init(&mdcontext);+ MD5Update(&mdcontext, buf, bp);+ MD5Final(&mdcontext);+ bcopy(&mdcontext.digest, pad+pp, MD5_LEN);+ + pp+=MD5_LEN;+ }++ free(buf);+ return(pad);+ +} /* _tac_md5_pad */++/* this function simply XORs each byte in buffer with+ byte in pad; this is used both for encryption and+ decryption, since XOR is symmetrical */+void _tac_crypt(u_char *buf, HDR *th, int length) {+ int i;+ u_char *pad;+ + /* null operation if no encryption requested */+ if(th->encryption == TAC_PLUS_ENCRYPTED) {+ + pad=_tac_md5_pad(length, th);+ + for(i=0; i<length; i++) {+ *(buf+i) ^= pad[i];+ }+ + free(pad);+ + } else {+ syslog(LOG_WARNING, "using no TACACS+ encryption");+ }+} /* _tac_crypt */++void *xcalloc(size_t nmemb, size_t size) {+ register void *val = calloc(nmemb, size);+ if(val == 0) {+ syslog(LOG_ERR, "%s: calloc(%u,%u) failed", __FUNCTION__, + nmemb, size);+ exit(1);+ }+ return val;+}++void *xrealloc(void *ptr, size_t size) {+ register void *val = realloc(ptr, size);+ if(val == 0) {+ syslog(LOG_ERR, "%s: realloc(%u) failed", __FUNCTION__, size);+ exit(1);+ }+ return val;+}diff -ruN ppp-2.2.0g/pppd/auth_tac.h ppp-2.2.0g.tacacs/pppd/auth_tac.h--- ppp-2.2.0g/pppd/auth_tac.h Thu Jan 1 01:00:00 1970+++ ppp-2.2.0g.tacacs/pppd/auth_tac.h Mon Feb 16 18:06:14 1998@@ -0,0 +1,40 @@+/*+ * Copyright 1997 by Pawel Krawczyk <kravietz@ceti.com.pl>+ *+ * See http://www.ceti.com.pl/~kravietz/progs/tacacs.html+ * for details.+ *+ */++#ifndef _AUTH_TAC_H+#define _AUTH_TAC_H++#if defined(DEBUGTAC) && !defined(TACDEBUG)+#define TACDEBUG(x) syslog x;+#else+#define TACDEBUG(x)+#endif++extern int tac_ver_major;+extern int tac_ver_minor;++extern int tac_connect(u_long *server, int servers);+extern int tac_authen_pap_send(int fd, char *user, char *pass, char *tty);+extern char *tac_authen_pap_read(int fd);+extern HDR *_tac_req_header(u_char type);+extern void _tac_crypt(u_char *buf, HDR *th, int length);+extern u_char *_tac_md5_pad(int len, HDR *hdr);+extern void tac_add_attrib(struct tac_attrib *attr, char *name, char *value);+extern void tac_free_attrib(struct tac_attrib *attr);+extern int tac_account_send(int fd, int type, char *user, char *tty,+ struct tac_attrib *attr);+extern char *tac_account_read(int fd);+extern void *xcalloc(size_t nmemb, size_t size);+extern void *xrealloc(void *ptr, size_t size);+extern char *_tac_check_header(HDR *th, int type);+extern int tac_author_send(int fd, char *username, char *tty, + struct tac_attrib *attr);+extern struct areply *tac_author_read(int fd);++#endif+diff -ruN ppp-2.2.0g/pppd/ipcp.c ppp-2.2.0g.tacacs/pppd/ipcp.c--- ppp-2.2.0g/pppd/ipcp.c Fri Nov 24 01:00:37 1995+++ ppp-2.2.0g.tacacs/pppd/ipcp.c Mon Feb 16 18:10:15 1998@@ -37,6 +37,22 @@ #include "ipcp.h" #include "pathnames.h" +#ifdef USE_TACACS_PLUS+#ifdef _linux_+#include <net/if.h>+#include <linux/if_ppp.h>+#endif+#include <time.h>+#include <unistd.h>+#include <sys/ioctl.h>+#include "tacplus.h"+#include "auth_tac.h"+#include "magic.h"+extern char *tac_username;+extern int task_id;+struct ifpppstatsreq treq;+#endif+ /* global vars */ ipcp_options ipcp_wantoptions[NUM_PPP]; /* Options that we want to request */ ipcp_options ipcp_gotoptions[NUM_PPP]; /* Options that peer ack'd */@@ -1028,6 +1044,11 @@ u_int32_t mask; ipcp_options *ho = &ipcp_hisoptions[f->unit]; ipcp_options *go = &ipcp_gotoptions[f->unit];+#ifdef USE_TACACS_PLUS+ char *msg;+ char *tty;+ struct tac_attrib *attr;+#endif IPCPDEBUG((LOG_INFO, "ipcp: up")); go->default_route = 0;@@ -1053,13 +1074,64 @@ /* * Check that the peer is allowed to use the IP address it wants. */- if (!auth_ip_addr(f->unit, ho->hisaddr)) {+ if (!auth_ip_addr(f->unit, ho->hisaddr) +#ifdef USE_TACACS_PLUS+ && (!tac_authorize && usetacacs)+#endif+ ) { syslog(LOG_ERR, "Peer is not authorized to use remote address %s", ip_ntoa(ho->hisaddr)); ipcp_close(f->unit); return; } +#ifdef USE_TACACS_PLUS+ if(usetacacs) {+ /* this is needed both by acct and author */+ tty=devnam;+ if(strncmp(tty, "/dev/", 5) == 0) tty+=5; + }++ if(tac_authorize && usetacacs) {+ /* ask for authorization to provide IP to the peer */+ int tac_fd;+ struct areply *arep;++ TACDEBUG((LOG_DEBUG, "ipcp_up: sending author request for %s", \+ ip_ntoa(ho->hisaddr)))+ attr=(struct tac_attrib *)xcalloc(1, sizeof(struct tac_attrib));+ tac_add_attrib(attr, "service", "ppp");+ tac_add_attrib(attr, "protocol", "ip"); /* ask for IPCP */+ tac_add_attrib(attr, "addr", ip_ntoa(ho->hisaddr));++ tac_fd=tac_connect(tac_server, tac_servers);++ if(tac_author_send(tac_fd, tac_username, tty, attr) < 0) {+ ipcp_close(f->unit);+ TACDEBUG((LOG_DEBUG, "ipcp_up: error sending request"))+ return;+ }++ arep = tac_author_read(tac_fd);++ if(arep->status != AUTHOR_STATUS_PASS_ADD &&+ arep->status != AUTHOR_STATUS_PASS_REPL) {+ syslog(LOG_ERR, "IPCP authorization failure: %s", arep->msg);+ ipcp_close(f->unit);+ return;+ }+ TACDEBUG((LOG_DEBUG, "ipcp_up: successful authorization: %s", \+ arep->msg));++ /* TODO: check arep->attrib and add to+ * ipcp_wantoptions[f->unit].hisaddr + */++ close(tac_fd);+ tac_free_attrib(attr);+ }+#endif+ syslog(LOG_NOTICE, "local IP address %s", ip_ntoa(go->ouraddr)); syslog(LOG_NOTICE, "remote IP address %s", ip_ntoa(ho->hisaddr)); @@ -1093,6 +1165,40 @@ if (sifproxyarp(f->unit, ho->hisaddr)) go->proxy_arp = 1; +#ifdef USE_TACACS_PLUS+ if(tac_accounting && usetacacs) {+ char buf[40]; + int tac_fd;++ TACDEBUG((LOG_NOTICE, "ipcp_up: start accounting"));+ attr=(struct tac_attrib *)xcalloc(1, sizeof(struct tac_attrib));+ sprintf(buf, "%lu", time(0));+ tac_add_attrib(attr, "start_time", buf);+ task_id=magic();+ sprintf(buf, "%u", task_id);+ tac_add_attrib(attr, "task_id", buf);+ tac_add_attrib(attr, "service", "ppp");+ tac_add_attrib(attr, "protocol", "ip");+ tac_add_attrib(attr, "addr", ip_ntoa(ho->hisaddr));+ + tac_fd=tac_connect(tac_server, tac_servers);++ if(tac_fd) {+ tac_account_send(tac_fd, TAC_PLUS_ACCT_FLAG_START,+ tac_username, tty, attr);+ + tac_free_attrib(attr);++ if(tac_account_read(tac_fd) != NULL) + syslog(LOG_WARNING,+ "TACACS+ accounting start failed");++ close(tac_fd); + }+ TACDEBUG((LOG_NOTICE, "ipcp_up: start accounting done"));+ }+#endif+ /* * Execute the ip-up script, like this: * /etc/ppp/ip-up interface tty speed local-IP remote-IP@@ -1118,6 +1224,78 @@ ouraddr = ipcp_gotoptions[f->unit].ouraddr; hisaddr = ipcp_hisoptions[f->unit].hisaddr;++#ifdef USE_TACACS_PLUS+ /* get interface statistics for accounting */++ if(tac_accounting && usetacacs) {+ char buf[40];+ int tac_fd, reqfd;+ struct tac_attrib *attr;+ char *tty;++ tty=devnam;+ if(strncmp(tty, "/dev/", 5) == 0) tty+=5; ++ bzero(&treq, sizeof(treq));++ /* get interface statistics */+ reqfd = socket(AF_INET, SOCK_DGRAM, 0);++#ifdef _linux_+ treq.stats_ptr = (caddr_t) &treq.stats;+#endif++ if(reqfd < 0)+ syslog(LOG_DEBUG,+ "cannot get PPP statistics for %s (socket): %m", ifname);+ else {+ sprintf(treq.ifr__name, "%s", ifname);+ if(ioctl(reqfd, SIOCGPPPSTATS, &treq) < 0)+ syslog(LOG_DEBUG,+ "cannot get PPP statistics for %s (ioctl): %m", ifname);+ }++ /* send stop accounting packet */++ TACDEBUG((LOG_DEBUG, "ipcp_down: stop accounting"))+ attr=(struct tac_attrib *) xcalloc(1, sizeof(struct tac_attrib));++ sprintf(buf, "%lu", time(0));+ tac_add_attrib(attr, "stop_time", buf);+ sprintf(buf, "%u", task_id);+ tac_add_attrib(attr, "task_id", buf);+ tac_add_attrib(attr, "service", "ppp");+ tac_add_attrib(attr, "protocol", "ip");++ if(((treq.stats).p).ppp_obytes) {+ sprintf(buf, "%u", ((treq.stats).p).ppp_obytes);+ tac_add_attrib(attr, "bytes_out", buf);+ sprintf(buf, "%u", ((treq.stats).p).ppp_ibytes);+ tac_add_attrib(attr, "bytes_in", buf);+ sprintf(buf, "%u", ((treq.stats).p).ppp_opackets);+ tac_add_attrib(attr, "paks_out", buf);+ sprintf(buf, "%u", ((treq.stats).p).ppp_ipackets);+ tac_add_attrib(attr, "paks_in", buf);+ }++ tac_fd=tac_connect(tac_server, tac_servers);++ if(tac_fd) {+ tac_account_send(tac_fd, TAC_PLUS_ACCT_FLAG_STOP, + tac_username, tty, attr);++ tac_free_attrib(attr);++ if(tac_account_read(tac_fd) != NULL) + syslog(LOG_DEBUG, "TACACS+ accounting stop failed");++ close(tac_fd);+ }+ TACDEBUG((LOG_DEBUG, "ipcp_down: stop accounting done"))+ }+#endif+ if (ipcp_gotoptions[f->unit].proxy_arp) cifproxyarp(f->unit, hisaddr); if (ipcp_gotoptions[f->unit].default_route) diff -ruN ppp-2.2.0g/pppd/lcp.c ppp-2.2.0g.tacacs/pppd/lcp.c--- ppp-2.2.0g/pppd/lcp.c Fri Apr 12 15:10:31 1996+++ ppp-2.2.0g.tacacs/pppd/lcp.c Sun Feb 1 02:47:06 1998@@ -1489,6 +1489,7 @@ lcp_down(f) fsm *f; {+ lcp_echo_lowerdown(f->unit); ccp_lowerdown(f->unit); ipcp_lowerdown(f->unit);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -