⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rlm_jradius.c

📁 使用最广泛的radius的linux的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
  return 0;}/* *     Pack an array of bytes into a byte array buffer */static int pack_bytes(byte_array * ba, unsigned char *d, unsigned int dlen){  if (ba->left < dlen) return -1;  memcpy((void *)(ba->b + ba->pos), d, dlen);  ba->pos  += dlen;  ba->left -= dlen;  return 0;}/* *     Pack an integer into a byte array buffer (adjusting for byte-order) */static int pack_uint32(byte_array * ba, uint32_t i){  if (ba->left < 4) return -1;  i = htonl(i);  memcpy((void *)(ba->b + ba->pos), (void *)&i, 4);  ba->pos  += 4;  ba->left -= 4;  return 0;}/* *     Pack one byte array buffer into another byte array buffer */static int pack_array(byte_array * ba, byte_array * a){  if (ba->left < a->pos) return -1;  memcpy((void *)(ba->b + ba->pos), (void *)a->b, a->pos);  ba->pos  += a->pos;  ba->left -= a->pos;  return 0;}/* *     Pack radius attributes into a byte array buffer */static int pack_vps(byte_array * ba, VALUE_PAIR * vps){  uint32_t i;  VALUE_PAIR * vp;  for (vp = vps; vp != NULL; vp = vp->next) {    radlog(L_DBG, LOG_PREFIX "packing attribute %s (type: %d; len: %d)", 	   vp->name, vp->attribute, vp->length);    i = vp->attribute;		/* element is int, not uint32_t */    if (pack_uint32(ba, i) == -1) return -1;    i = vp->length;    if (pack_uint32(ba, i) == -1) return -1;    i = vp->operator;    if (pack_uint32(ba, i) == -1) return -1;    switch (vp->type) {      case PW_TYPE_INTEGER:      case PW_TYPE_DATE:	if (pack_uint32(ba, vp->lvalue) == -1) return -1;	break;      case PW_TYPE_IPADDR:	if (pack_bytes(ba, (void *)&vp->vp_ipaddr, vp->length) == -1) return -1;	break;      default:	if (pack_bytes(ba, (void *)vp->vp_octets, vp->length) == -1) return -1;	break;    }  }  return 0;}/* *     Pack a radius packet into a byte array buffer */static int pack_packet(byte_array * ba, RADIUS_PACKET * p){  /*unsigned char code = p->code;*/  unsigned char buff[HALF_MESSAGE_LEN];  byte_array pba;  init_byte_array(&pba, buff, sizeof(buff));  if (pack_vps   (&pba, p->vps) == -1) return -1;  radlog(L_DBG, LOG_PREFIX "packing packet with code: %d (attr length: %d)", p->code, pba.pos);  if (pack_byte  (ba, p->code)  == -1) return -1;  if (pack_byte  (ba, p->id)    == -1) return -1;  if (pack_uint32   (ba, pba.pos)  == -1) return -1;  if (pba.pos == 0) return 0;  if (pack_array (ba, &pba)     == -1) return -1;  return 0;}static int pack_request(byte_array * ba, REQUEST *r){  unsigned char buff[HALF_MESSAGE_LEN];  byte_array pba;  init_byte_array(&pba, buff, sizeof(buff));  if (pack_vps   (&pba, r->config_items) == -1) return -1;  if (pack_uint32   (ba, pba.pos)  == -1) return -1;  if (pba.pos == 0) return 0;  if (pack_array (ba, &pba)     == -1) return -1;        return 0;}/* *     Read a single byte from socket */static int read_byte(JRSOCK *jrsock, unsigned char *b){  return (read(jrsock->con.sock, b, 1) == 1) ? 0 : -1;}static void unpack_uint32(unsigned char *c, uint32_t *i){  uint32_t ii;  memcpy((void *)&ii, c, 4);  *i = ntohl(ii);}/* *     Read an integer from the socket (adjusting for byte-order) */static int read_uint32(JRSOCK *jrsock, uint32_t *i){  uint32_t ii;  if (read(jrsock->con.sock, &ii, 4) != 4) return -1;  *i = ntohl(ii);  return 0;}/* *     Read a value-pair list from the socket */static int read_vps(JRSOCK *jrsock, VALUE_PAIR **pl, int plen){  VALUE_PAIR *vp;  unsigned char buff[MESSAGE_LEN];  uint32_t alen, atype, aop;  int rlen = 0;    while (rlen < plen) {    if (read_uint32 (jrsock, &atype) == -1) return -1; rlen += 4;    if (read_uint32 (jrsock, &alen)  == -1) return -1; rlen += 4;    if (read_uint32 (jrsock, &aop)   == -1) return -1; rlen += 4;     radlog(L_DBG, LOG_PREFIX "reading attribute: type=%d; len=%d", atype, alen);    if (alen >= sizeof(buff)) {      radlog(L_ERR, LOG_PREFIX "packet value too large (len: %d)", alen);      return -1;    }    if (read(jrsock->con.sock, buff, alen) != (int)alen) return -1; rlen += alen;    buff[alen]=0;    /*     *     Create new attribute     */    vp = paircreate(atype, -1);    vp->operator = aop;    if (vp->type == -1) {      /*       *     FreeRADIUS should know about the same attributes that JRadius knows       */      radlog(L_ERR, LOG_PREFIX "received attribute we do not recognize (type: %d)", atype);      pairbasicfree(vp);      continue;    }    /*     *     Fill in the attribute value based on type     */    switch (vp->type) {      case PW_TYPE_INTEGER:      case PW_TYPE_DATE:	{          unpack_uint32(buff, &vp->lvalue);	  vp->length = 4;	}	break;      case PW_TYPE_IPADDR:	memcpy((void *)&vp->vp_ipaddr, buff, 4);	vp->length = 4;	break;      default:        if (alen >= sizeof(vp->vp_octets)) alen = sizeof(vp->vp_octets) - 1;	memcpy((void *)vp->vp_octets, buff, alen);	vp->length = alen;	break;    }    /*     *     Add the attribute to the packet     */    pairadd(pl, vp);  }   return rlen;}/* *     Read a radius packet from the socket */static int read_packet(JRADIUS * inst, JRSOCK *jrsock, RADIUS_PACKET *p){  unsigned char code;  unsigned char id;  unsigned int plen;  if (read_byte (jrsock, &code) == -1) return -1;  if (read_byte (jrsock, &id)   == -1) return -1;  if (read_uint32  (jrsock, &plen) == -1) return -1;  radlog(L_DBG, LOG_PREFIX "reading packet: code=%d len=%d", (int)code, plen);  if (inst->allow_codechange)    if (code != p->code) {      radlog(L_INFO, LOG_PREFIX "changing packet code from %d to %d", p->code, code);      p->code = code;    }  if (inst->allow_idchange)    if (id != p->id) {      radlog(L_INFO, LOG_PREFIX "changing packet id from %d to %d", p->id, id);      p->id = id;    }    /*   *     Delete previous attribute list   */  pairfree(&p->vps);  if (plen == 0) return 0;  if (read_vps (jrsock, &p->vps, plen) == -1) return -1;  return 0;}static int read_request(JRSOCK *jrsock, REQUEST *p){  unsigned int plen;  if (read_uint32(jrsock, &plen) == -1) return -1;  radlog(L_DBG, LOG_PREFIX "reading request: config_item: len=%d", plen);  /*   *     Delete previous attribute list   */  pairfree(&p->config_items);  if (plen == 0) return 0;  if (read_vps(jrsock, &p->config_items, plen) == -1) return -1;  return 0;}static int rlm_jradius_call(char func, void *instance, REQUEST *req, int isproxy){  JRADIUS        * inst    = instance;  RADIUS_PACKET  * request = isproxy ? req->proxy : req->packet;  RADIUS_PACKET  * reply   = isproxy ? req->proxy_reply : req->reply;  JRSOCK         * jrsock  = 0;  JRSOCK           sjrsock;  int exitstatus = inst->onfail;  unsigned char rcode, pcount;  unsigned char buff[MESSAGE_LEN];  byte_array ba;  char * n = inst->name;  unsigned int nlen = strlen(n);  const char * err = 0;  int rc, attempt2=0;#define W_ERR(s) { err=s; goto packerror;  }#define R_ERR(s) { err=s; goto parseerror; }  if (inst->keepalive) {    jrsock = get_socket(inst);    if (!jrsock) return exitstatus;  } else {    jrsock = &sjrsock;    memset(jrsock, 0, sizeof(*jrsock));    jrsock->state = not_connected;  }  init_byte_array(&ba, buff, sizeof(buff));  pcount = 0;  if (request) pcount++;  if (reply) pcount++;  /*   *     Create byte array to send to jradius   */  if ((rc = pack_uint32    (&ba, nlen))                  == -1)  W_ERR("pack_uint32(nlen)");  if ((rc = pack_bytes  (&ba, (void *)n, nlen))       == -1)  W_ERR("pack_bytes(name)");  if ((rc = pack_byte   (&ba, func))                  == -1)  W_ERR("pack_byte(fun)");  if ((rc = pack_byte   (&ba, pcount))                == -1)  W_ERR("pack_byte(pcnt)");  if (pcount > 0 && (rc = pack_packet (&ba, request)) == -1)  W_ERR("pack_packet(req)");  if (pcount > 1 && (rc = pack_packet (&ba, reply))   == -1)  W_ERR("pack_packet(rep)");  if ((rc = pack_request(&ba, req))                   == -1)  W_ERR("pack_request()");  /*   *     Send data   */ start_over:  if (jrsock->state == not_connected) {    if (attempt2) radlog(L_ERR, LOG_PREFIX "reconnecting socket id %d", jrsock->id);    if (!connect_socket(jrsock, inst)) {      if (attempt2) radlog(L_ERR, LOG_PREFIX "could not reconnect socket %d, giving up", jrsock->id);      goto cleanup;    }  }  radlog(L_DBG, LOG_PREFIX "sending %d bytes to socket %d", ba.pos, jrsock->id);  if (socket_send(jrsock, ba.b, ba.pos) != (int)ba.pos ||      (rc = read_byte (jrsock, &rcode)) == -1) {    /*     *   With an error on the write or the first read, try closing the socket     *   and reconnecting to see if that improves matters any (tries this only once)     */    radlog(L_ERR, LOG_PREFIX "error sending request with socket %d", jrsock->id);    if (!inst->keepalive || attempt2) W_ERR("socket_send/first_read");    close_socket(inst, jrsock);    attempt2 = 1;    goto start_over;  }  /*   *     Read result   */  if ((rc = read_byte (jrsock, &pcount)) == -1)  R_ERR("read_byte(pcnt)");  radlog(L_DBG, LOG_PREFIX "return code %d; receiving %d packets", (int)rcode, (int)pcount);  if (pcount > 0 && request) if ((rc = read_packet (inst, jrsock, request)) == -1)  R_ERR("read_packet(req)");  if (pcount > 1 && reply)   if ((rc = read_packet (inst, jrsock, reply))   == -1)  R_ERR("read_packet(rep)");  if ((rc = read_request (jrsock, req)) == -1) R_ERR("read_request()");  /*   *    Since we deleted all the attribute lists in the request,   *    we need to reconfigure a few pointers in the REQUEST object   */  if (req->username) {    req->username = pairfind(request->vps, PW_USER_NAME);  }  if (req->password) {    req->password = pairfind(request->vps, PW_PASSWORD);    if (!req->password) req->password = pairfind(request->vps, PW_CHAP_PASSWORD);  }  /*   *    All done, set return code and cleanup   */  exitstatus = (int)rcode;  goto cleanup; parseerror:  radlog(L_ERR, LOG_PREFIX "problem parsing the data [%s]",err);  if (inst->keepalive) close_socket(inst, jrsock);  goto cleanup; packerror:  radlog(L_ERR, LOG_PREFIX "problem packing the data[%s]",err);  if (inst->keepalive) close_socket(inst, jrsock); cleanup:  if (inst->keepalive)     release_socket(inst, jrsock);  else      close_socket(inst, jrsock);  return exitstatus;}static int jradius_authenticate(void *instance, REQUEST *request){  return rlm_jradius_call(JRADIUS_authenticate, instance, request, 0);}static int jradius_authorize(void *instance, REQUEST *request){  return rlm_jradius_call(JRADIUS_authorize, instance, request, 0);}static int jradius_preacct(void *instance, REQUEST *request){  return rlm_jradius_call(JRADIUS_preacct, instance, request, 0);}static int jradius_accounting(void *instance, REQUEST *request){  return rlm_jradius_call(JRADIUS_accounting, instance, request, 0);}static int jradius_checksimul(void *instance, REQUEST *request){  return rlm_jradius_call(JRADIUS_checksimul, instance, request, 0);}static int jradius_pre_proxy(void *instance, REQUEST *request){  return rlm_jradius_call(JRADIUS_pre_proxy, instance, request, 1);}static int jradius_post_proxy(void *instance, REQUEST *request){  return rlm_jradius_call(JRADIUS_post_proxy, instance, request, 1);}static int jradius_post_auth(void *instance, REQUEST *request){  return rlm_jradius_call(JRADIUS_post_auth, instance, request, 0);}static int jradius_detach(void *instance){  JRADIUS *inst = (JRADIUS *) instance;  free_socketpool(inst);  free(inst);  return 0;}module_t rlm_jradius = {  RLM_MODULE_INIT,  "jradius",  RLM_TYPE_THREAD_SAFE,  jradius_instantiate,  jradius_detach,  {    jradius_authenticate,    jradius_authorize,    jradius_preacct,    jradius_accounting,    jradius_checksimul,    jradius_pre_proxy,    jradius_post_proxy,    jradius_post_auth  },};

⌨️ 快捷键说明

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