📄 pppd-2.2.0g.patch
字号:
+ struct tac_attrib *a;+ int i = 0; /* arg count */+ int pkt_len = 0;+ int w; /* write count */+ u_char *pkt;+ u_char *pktp;+ int ret = 0;++ th=_tac_req_header(TAC_PLUS_AUTHOR);++ /* set header options */+ th->version=TAC_PLUS_VER_0;+ th->encryption=tac_encryption ? TAC_PLUS_ENCRYPTED : TAC_PLUS_CLEAR;++ TACDEBUG((LOG_DEBUG, "%s: user '%s', tty '%s', encrypt: %s", \+ __FUNCTION__, user, \+ tty, tac_encryption ? "yes" : "no"))+ + user_len=(u_char) strlen(user);+ port_len=(u_char) strlen(tty);++ tb.authen_method=AUTHEN_METH_TACACSPLUS;+ tb.priv_lvl=TAC_PLUS_PRIV_LVL_MIN;+ tb.authen_type=TAC_PLUS_AUTHEN_TYPE_PAP;+ tb.service=TAC_PLUS_AUTHEN_SVC_PPP;+ tb.user_len=user_len;+ tb.port_len=port_len;+ tb.rem_addr_len=0;++ /* allocate packet */+ pkt=(u_char *) xcalloc(1, TAC_AUTHOR_REQ_FIXED_FIELDS_SIZE);+ pkt_len=sizeof(tb);++ /* fill attribute length fields */+ a = attr;+ while(a->attr != 0 && a) {+ + pktp=pkt + pkt_len; /* save before it's increased */+ pkt_len += sizeof(a->attr_len);+ pkt = xrealloc(pkt, pkt_len); + bcopy(&a->attr_len, pktp, sizeof(a->attr_len));+ i++;++ a = a->next;+ }++ /* fill the arg count field and add the fixed fields to packet */+ tb.arg_cnt = i;+ bcopy(&tb, pkt, TAC_AUTHOR_REQ_FIXED_FIELDS_SIZE);++#define PUTATTR(data, len) \+ pktp = pkt + pkt_len; \+ pkt_len += len; \+ pkt = xrealloc(pkt, pkt_len); \+ bcopy(data, pktp, len);++ /* fill user and port fields */+ /*+ pktp = pkt + pkt_len;+ pkt_len += user_len;+ pkt = xrealloc(pkt, pkt_len);+ bcopy(user, pktp, user_len);+ */++ PUTATTR(user, user_len)+ + /* + pktp = pkt + pkt_len;+ pkt_len += port_len;+ pkt = xrealloc(pkt, pkt_len);+ bcopy(tty, pktp, port_len);+ */+ + PUTATTR(tty, port_len)++ /* fill attributes */+ a = attr;+ while(a->attr != 0 && a) {+ /*+ pktp = pkt + pkt_len;+ pkt_len += a->attr_len;+ pkt = xrealloc(pkt, pkt_len);+ bcopy(a->attr, pktp, a->attr_len);+ */+ PUTATTR(a->attr, a->attr_len)++ a = a->next;+ }++ /* finished building packet, fill len_from_header in header */+ th->datalength = htonl(pkt_len);++ /* write header */+ w=write(fd, th, TAC_PLUS_HDR_SIZE);++ if(w < TAC_PLUS_HDR_SIZE) {+ syslog(LOG_ERR, "author hdr send failed: wrote %d of %d", w,+ TAC_PLUS_HDR_SIZE);+ ret = -1;+ }+ + /* encrypt packet body */+ _tac_crypt(pkt, th, pkt_len);++ /* write body */+ w=write(fd, pkt, pkt_len);+ if(w < pkt_len) {+ syslog(LOG_ERR, "author body send failed: wrote %d of %d", w,+ pkt_len);+ ret = -1;+ }++ free(pkt);+ free(th);++ return(ret);+}++struct areply *tac_author_read(int fd) {+ HDR th;+ struct author_reply *tb;+ int len_from_header, r, len_from_body;+ char *pktp;+ char *msg = NULL;++ struct areply *re = (struct areply *) xcalloc(1, sizeof(struct areply));+ + r=read(fd, &th, TAC_PLUS_HDR_SIZE);+ if(r < TAC_PLUS_HDR_SIZE) {+ syslog(LOG_ERR,+ "short author header, %d of %d: %m",+ r, TAC_PLUS_HDR_SIZE);+ re->msg = system_err_msg;+ re->status = AUTHOR_STATUS_ERROR;+ return(re);+ }++ /* check header consistency */+ msg = _tac_check_header(&th, TAC_PLUS_AUTHOR);+ if(msg != NULL) {+ /* no need to process body if header is broken */+ re->msg = msg;+ re->status = AUTHOR_STATUS_ERROR;+ return(re); + }++ len_from_header=ntohl(th.datalength);+ tb=(struct author_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,+ "short author body, %d of %d: %m",+ r, len_from_header);+ re->msg = system_err_msg;+ re->status = AUTHOR_STATUS_ERROR;+ return(re);+ }++ /* decrypt the body */+ _tac_crypt((u_char *) tb, &th, len_from_header);++ /* check consistency of the reply body+ * len_from_header = declared in header+ * len_from_body = value computed from body fields+ */+ len_from_body = TAC_AUTHOR_REPLY_FIXED_FIELDS_SIZE ++ tb->msg_len + tb->data_len;+ + pktp = (u_char *) tb + TAC_AUTHOR_REPLY_FIXED_FIELDS_SIZE;+ + for(r = 0; r < tb->arg_cnt; r++) {+ len_from_body += sizeof(u_char); /* add arg length field's size*/+ len_from_body += *pktp; /* add arg length itself */+ }+ + if(len_from_header != len_from_body) {+ syslog(LOG_ERR,+ "inconsistent author reply body, incorrect key?");+ re->msg = system_err_msg;+ re->status = AUTHOR_STATUS_ERROR;+ return(re);+ }++ /* packet seems to be consistent, prepare return messages */+ /* server message for user */+ if(tb->msg_len) {+ char *msg = (char *) xcalloc(1, tb->msg_len+1);+ bcopy(tb+TAC_AUTHOR_REPLY_FIXED_FIELDS_SIZE+ + (tb->arg_cnt)*sizeof(u_char),+ msg, tb->msg_len);+ re->msg = msg;+ }++ /* server message to syslog */+ if(tb->data_len) {+ char *smsg=(char *) xcalloc(1, tb->data_len+1);+ bcopy(tb + TAC_AUTHOR_REPLY_FIXED_FIELDS_SIZE+ + (tb->arg_cnt)*sizeof(u_char)+ + tb->msg_len, smsg, + tb->data_len);+ syslog(LOG_ERR, "author failed: %s", smsg);+ free(smsg);+ }++ /* prepare status */+ switch(tb->status) {+ /* success conditions */+ case AUTHOR_STATUS_PASS_ADD:+ case AUTHOR_STATUS_PASS_REPL:+ if(!re->msg) re->msg=author_ok_msg;+ re->status=tb->status;+ break;++ /* authorization failure conditions */+ /* failing to follow is allowed by RFC, page 23 */+ case AUTHOR_STATUS_FOLLOW: + case AUTHOR_STATUS_FAIL:+ if(!re->msg) re->msg=author_fail_msg;+ re->status=AUTHOR_STATUS_FAIL;+ break;++ /* error conditions */ + case AUTHOR_STATUS_ERROR:+ default:+ if(!re->msg) re->msg=author_err_msg;+ re->status=AUTHOR_STATUS_ERROR;+ }++ free(tb); + TACDEBUG((LOG_DEBUG, "%s: server replied '%s'", __FUNCTION__, \+ re->msg))+ return(re);+ +}++/* checks given reply header for possible inconsistencies:+ * - type other tha expected+ * - sequence number other than 2+ * - session id different from one sent in request+ * returns pointer to error message+ * or NULL when header is correct+ */+char *_tac_check_header(HDR *th, int type) {++ if(th->type != type) {+ syslog(LOG_ERR,+ "unrelated reply, type %d, expected %d", th->type,+ type);+ 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);+ }+ + return(NULL); /* header is ok */ ++} /* check header */++int tac_account_send(int fd, int type, char *user, char *tty,+ struct tac_attrib *attr) {+ HDR *th;+ struct acct tb;+ u_char user_len, port_len;+ struct tac_attrib *a;+ int i = 0; /* arg count */+ int pkt_len = 0;+ int w; /* write count */+ u_char *pkt;+ u_char *pktp;+ int ret = 0;++ th=_tac_req_header(TAC_PLUS_ACCT);++ /* set header options */+ th->version=TAC_PLUS_VER_0;+ th->encryption=tac_encryption ? TAC_PLUS_ENCRYPTED : TAC_PLUS_CLEAR;++ TACDEBUG((LOG_DEBUG, "%s: user '%s', tty '%s', encrypt: %s, type: %s", \+ __FUNCTION__, user, tty, \+ (tac_encryption) ? "yes" : "no", \+ (type == TAC_PLUS_ACCT_FLAG_START) ? "START" : "STOP"))+ + user_len=(u_char) strlen(user);+ port_len=(u_char) strlen(tty);++ tb.flags=(u_char) type;+ tb.authen_method=AUTHEN_METH_TACACSPLUS;+ tb.priv_lvl=TAC_PLUS_PRIV_LVL_MIN;+ tb.authen_type=TAC_PLUS_AUTHEN_TYPE_PAP;+ tb.authen_service=TAC_PLUS_AUTHEN_SVC_PPP;+ tb.user_len=user_len;+ tb.port_len=port_len;+ tb.rem_addr_len=0;++ /* allocate packet */+ pkt=(u_char *) xcalloc(1, TAC_ACCT_REQ_FIXED_FIELDS_SIZE);+ pkt_len=sizeof(tb);++ /* fill attribute length fields */+ a = attr;+ while(a->attr != 0 && a) {+ + pktp=pkt + pkt_len; /* save before it's increased */+ pkt_len += sizeof(a->attr_len);+ pkt = xrealloc(pkt, pkt_len); + bcopy(&a->attr_len, pktp, sizeof(a->attr_len));+ i++;++ a = a->next;+ }++ /* fill the arg count field and add the fixed fields to packet */+ tb.arg_cnt = i;+ bcopy(&tb, pkt, TAC_ACCT_REQ_FIXED_FIELDS_SIZE);++#define PUTATTR(data, len) \+ pktp = pkt + pkt_len; \+ pkt_len += len; \+ pkt = xrealloc(pkt, pkt_len); \+ bcopy(data, pktp, len);++ /* fill user and port fields */+ /*+ pktp = pkt + pkt_len;+ pkt_len += user_len;+ pkt = xrealloc(pkt, pkt_len);+ bcopy(user, pktp, user_len);+ */++ PUTATTR(user, user_len)+ + /* + pktp = pkt + pkt_len;+ pkt_len += port_len;+ pkt = xrealloc(pkt, pkt_len);+ bcopy(tty, pktp, port_len);+ */+ + PUTATTR(tty, port_len)++ /* fill attributes */+ a = attr;+ while(a->attr != 0 && a) {+ /*+ pktp = pkt + pkt_len;+ pkt_len += a->attr_len;+ pkt = xrealloc(pkt, pkt_len);+ bcopy(a->attr, pktp, a->attr_len);+ */+ PUTATTR(a->attr, a->attr_len)++ a = a->next;+ }++ /* finished building packet, fill len_from_header in header */+ th->datalength = htonl(pkt_len);++ /* write header */+ w=write(fd, th, TAC_PLUS_HDR_SIZE);++ if(w < TAC_PLUS_HDR_SIZE) {+ syslog(LOG_ERR, "acct hdr send failed: wrote %d of %d", w,+ TAC_PLUS_HDR_SIZE);+ ret = -1;+ }+ + /* encrypt packet body */+ _tac_crypt(pkt, th, pkt_len);++ /* write body */+ w=write(fd, pkt, pkt_len);+ if(w < pkt_len) {+ syslog(LOG_ERR, "acct body send failed: wrote %d of %d", w,+ pkt_len);+ ret = -1;+ }++ free(pkt);+ free(th);++ return(ret);+}++/* this function sends a packet do TACACS+ server, asking+ * for validation of given username and password+ */+int tac_authen_pap_send(int fd, char *user, char *pass, char *tty)+{+ HDR *th; /* TACACS+ packet header */+ struct authen_start tb; /* message body */+ int user_len, port_len, pass_len, bodylength, w;+ int pkt_len=0;+ u_char *pkt;+ int ret=0;++ th=_tac_req_header(TAC_PLUS_AUTHEN);++ /* set some header options */+ th->version=TAC_PLUS_VER_1;+ th->encryption=tac_encryption ? TAC_PLUS_ENCRYPTED : TAC_PLUS_CLEAR;++ TACDEBUG((LOG_DEBUG, "%s: user '%s', pass '%s', tty '%s', encrypt: %s", \+ __FUNCTION__, user, pass, tty, \+ (tac_encryption) ? "yes" : "no")) + + /* get size of submitted data */+ user_len=strlen(user);+ port_len=strlen(tty);+ pass_len=strlen(pass);++ /* fill the body of message */+ tb.action=TAC_PLUS_AUTHEN_LOGIN;+ tb.priv_lvl=TAC_PLUS_PRIV_LVL_MIN;+ tb.authen_type=TAC_PLUS_AUTHEN_TYPE_PAP;+ tb.service=TAC_PLUS_AUTHEN_SVC_PPP;+ tb.user_len=user_len;+ tb.port_len=port_len;+ tb.rem_addr_len=0; /* may be e.g Caller-ID in future */+ tb.data_len=pass_len;++ /* fill body length in header */+ bodylength=sizeof(tb) + user_len+ + port_len + pass_len; /* + rem_addr_len */++ th->datalength= htonl(bodylength);++ /* we can now write the header */+ w=write(fd, th, TAC_PLUS_HDR_SIZE);+ if(w < 0 || w < TAC_PLUS_HDR_SIZE) {+ syslog(LOG_ERR, "short write on PAP header: wrote %d of %d: %m", w, TAC_PLUS_HDR_SIZE);+ ret=-1;+ }++ /* build the packet */+ pkt=(u_char *) xcalloc(1, bodylength+10);++ bcopy(&tb, pkt+pkt_len, sizeof(tb)); /* packet body beginning */+ pkt_len+=sizeof(tb);+ bcopy(user, pkt+pkt_len, user_len); /* user */+ pkt_len+=user_len;+ bcopy(tty, pkt+pkt_len, port_len); /* tty */+ pkt_len+=port_len;+ bcopy(pass, pkt+pkt_len, pass_len); /* password */+ pkt_len+=pass_len;++ /* pkt_len == bodylength ? */+ if(pkt_len != bodylength) {+ TACDEBUG((LOG_DEBUG, "tac_authen_send: bodylength %d != pkt_len %d", bodylength, pkt_len));+ } + + /* encrypt the body */+ _tac_crypt(pkt, th, bodylength);++ w=write(fd, pkt, pkt_len);+ if(w < 0 || w < pkt_len) {+ syslog(LOG_ERR, "short write on PAP body: wrote %d of %d: %m", w, pkt_len);+ ret=-1;+ }++ free(pkt);+ free(th);++ return(ret);+} /* tac_authen_pap_send */++char *tac_account_read(int fd) {+ HDR th;+ struct acct_reply *tb;+ int len_from_header, r, len_from_body;+ char *msg = NULL;++ r=read(fd, &th, TAC_PLUS_HDR_SIZE);+ if(r < TAC_PLUS_HDR_SIZE) {+ syslog(LOG_ERR,+ "short PAP acct header, %d of %d: %m",+ r, TAC_PLUS_HDR_SIZE);+ return(system_err_msg);+ }++ /* check the reply fields in header */+ if(th.type != TAC_PLUS_ACCT) {+ syslog(LOG_ERR,+ "unrelated reply, type %d, expected %d", th.type,+ TAC_PLUS_ACCT);+ 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 acct_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->msg_len) + sizeof(tb->data_len) ++ sizeof(tb->status) + tb->msg_len + tb->data_len;++ if(len_from_header != len_from_body) {+ syslog(LOG_ERR,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -