示例#1
0
int DBUtil::QueryForString(char* buf, size_t buflen, const char* sql, ...)
{
    SQL_INST* sqlinst = (SQL_INST*)dbHandle_;
    if(sqlinst == 0) {
        radlog(L_CONS|L_ERROR, "[DBUtil::QueryForString] invalid instance");
        return -1;
    }

    char sqlbuf[4096];
    va_list args;
    va_start(args, sql);
    vsNprintf(sqlbuf, sizeof(sqlbuf), sql, args);
    va_end(args);

    Row row;
    int result = SelectFirstRowInternal(sqlinst, sqlbuf, row);
    if(result < 0)
        strNcpy(buf, "<DBERROR>", buflen);
    else if(result == 0)
        strNcpy(buf, "<NORESULT>", buflen);
    else
        strNcpy(buf, row[0].c_str(), buflen);

    return result;
}
示例#2
0
/*
 *	Set the SQL user name.
 *
 *	We don't call the escape function here. The resulting string
 *	will be escaped later in the queries xlat so we don't need to
 *	escape it twice. (it will make things wrong if we have an
 *	escape candidate character in the username)
 */
static int sql_set_user(SQL_INST *inst, REQUEST *request, char *sqlusername, const char *username)
{
	VALUE_PAIR *vp=NULL;
	char tmpuser[MAX_STRING_LEN];

	tmpuser[0] = '\0';
	sqlusername[0]= '\0';

	/* Remove any user attr we added previously */
	pairdelete(&request->packet->vps, PW_SQL_USER_NAME);

	if (username != NULL) {
		strNcpy(tmpuser, username, MAX_STRING_LEN);
	} else if (strlen(inst->config->query_user)) {
		radius_xlat(tmpuser, sizeof(tmpuser), inst->config->query_user, request, NULL);
	} else {
		return 0;
	}

	if (*tmpuser) {
		strNcpy(sqlusername, tmpuser, MAX_STRING_LEN);
		DEBUG2("rlm_sql (%s): sql_set_user escaped user --> '%s'",
		       inst->config->xlat_name, sqlusername);
		vp = pairmake("SQL-User-Name", sqlusername, 0);
		if (vp == NULL) {
			radlog(L_ERR, "%s", librad_errstr);
			return -1;
		}

		pairadd(&request->packet->vps, vp);
		return 0;
	}
	return -1;
}
示例#3
0
文件: dumpf.c 项目: csound/csound
int32_t krd4set_S(CSOUND *csound, KREAD4 *p)
{
    /* open in curdir or pathname */
    char soundiname[1024];
    if (UNLIKELY((p->format = (int32_t)*p->iformat) < 1 || p->format > 8)) {
      return csound->InitError(csound, Str("unknown format request"));
    }
    if (UNLIKELY(p->format == 2 || p->format == 3)) {
      return csound->InitError(csound,
                               Str("alaw and ulaw not implemented here"));
    }
    strNcpy(soundiname,  ((STRINGDAT *)p->ifilcod)->data, 1023);
    if (p->fdch.fd != NULL)
      fdclose(csound, &(p->fdch));
    p->fdch.fd = csound->FileOpen2(csound, &(p->f), CSFILE_STD, soundiname, "rb",
                                   "SFDIR;SSDIR", dumpf_format_table[p->format], 0);
    if (UNLIKELY(p->fdch.fd == NULL))
      return csound->InitError(csound, Str("Cannot open %s"), soundiname);
    fdrecord(csound, &p->fdch);
    if ((p->timcount = (int32_t)(*p->iprd * CS_EKR)) <= 0)
      p->timcount = 1;
    p->countdown = 0;
    p->k[0] = p->k[1] = p->k[2] = p->k[3] = FL(0.0);
    return OK;
}
示例#4
0
文件: dumpf.c 项目: csound/csound
int32_t kdmpset_p(CSOUND *csound, KDUMP *p)
{
    /* open in curdir or pathname */
    char soundoname[1024];
    if (UNLIKELY((p->format = (int32_t)*p->iformat) < 1 || p->format > 8)) {
      return csound->InitError(csound, Str("unknown format request"));
    }
    if (UNLIKELY(p->format == 2 || p->format == 3)) {
      return csound->InitError(csound,
                               Str("alaw and ulaw not implemented here"));
    }
    if (csound->ISSTRCOD(*p->ifilcod))
      strNcpy(soundoname, get_arg_string(csound, *p->ifilcod), 1023);
    else csound->strarg2name(csound, soundoname, p->ifilcod, "dumpk.", 0);
    if (p->fdch.fd != NULL)
      fdclose(csound, &(p->fdch));
    p->fdch.fd = csound->FileOpen2(csound, &(p->f), CSFILE_STD, soundoname,
                                   "wb", "", dumpf_format_table[p->format], 0);
    if (UNLIKELY(p->fdch.fd == NULL))
      return csound->InitError(csound, Str("Cannot open %s"), soundoname);
    fdrecord(csound, &p->fdch);
    if ((p->timcount = (int32_t)(*p->iprd * CS_EKR)) <= 0)
      p->timcount = 1;
    p->countdown = p->timcount;
    return OK;
}
示例#5
0
文件: dumpf.c 项目: csound/csound
int32_t krdsset_p(CSOUND *csound, KREADS *p)
{
    /* open in curdir or pathname */
    char soundiname[1024];
    if (csound->ISSTRCOD(*p->ifilcod))
      strNcpy(soundiname, get_arg_string(csound, *p->ifilcod), 1023);
    else csound->strarg2name(csound, soundiname, p->ifilcod, "readk.", 0);
    if (p->fdch.fd != NULL)
      fdclose(csound, &(p->fdch));
    p->fdch.fd = csound->FileOpen2(csound, &(p->f), CSFILE_STD, soundiname, "rb",
                                   "SFDIR;SSDIR", 0, 0);
    if (UNLIKELY(p->fdch.fd == NULL))
      return csound->InitError(csound, Str("Cannot open %s"), soundiname);
    fdrecord(csound, &p->fdch);
    if ((p->timcount = (int32_t)(*p->iprd * CS_EKR)) <= 0)
      p->timcount = 1;
    p->countdown = 0;
    p->lasts = (char*)csound->Malloc(csound, INITSIZE);
    p->lasts[0] = '\0';
     if (p->str->data == NULL) {
       p->str->data = csound->Calloc(csound, INITSIZE);
       p->str->size = INITSIZE;
    }
    return OK;
}
示例#6
0
文件: pvread.c 项目: csound/csound
int32_t pvreadset_(CSOUND *csound, PVREAD *p, int32_t stringname)
{
    char      pvfilnam[256];

    if (stringname==0){
      if (csound->ISSTRCOD(*p->ifilno))
        strNcpy(pvfilnam,get_arg_string(csound, *p->ifilno), MAXNAME);
      else csound->strarg2name(csound, pvfilnam, p->ifilno, "pvoc.",0);
    }
    else strNcpy(pvfilnam, ((STRINGDAT *)p->ifilno)->data, MAXNAME);

    if (pvocex_loadfile(csound, pvfilnam, p) == OK) {
      p->prFlg = 1;
      p->mybin = MYFLT2LRND(*p->ibin);
      return OK;
    }
    return NOTOK;
}
示例#7
0
文件: addr.c 项目: srsbsns/libsrsbsns
void addr_parse_hostspec(char *hoststr, size_t hoststr_sz,
		char *service, size_t service_sz, const char *hostspec)
{
	strNcpy(hoststr, hostspec + (hostspec[0] == '['), hoststr_sz);
	char *ptr = strchr(hoststr, ']');
	if (!ptr)
		ptr = hoststr;
	else
		*ptr++ = '\0';

	ptr = strchr(ptr, ':');
	if (ptr) {
		if (service && service_sz)
			strNcpy(service, ptr+1, service_sz);
		*ptr = '\0';
	} else {
		if (service && service_sz)
			service[0] = '\0';
	}
}
示例#8
0
文件: dumpf.c 项目: csound/csound
int32_t kreads(CSOUND *csound, KREADS *p)
{
    if (--p->countdown <= 0) {
      p->countdown = p->timcount;
      if (UNLIKELY(fgets(p->lasts, INITSIZE-1,  p->f)==NULL)) {
        csound->PerfError(csound, &(p->h), Str("Read failure in readks"));
      }
    }
    strNcpy((char*) p->str->data, p->lasts, INITSIZE);
    return OK;
}
示例#9
0
int cardJobLoadCfg(struct _cardJob *j,char *_iccid,char *filename) { // Loads Info from a file
if (!j) j = &cardJob;
if (!filename) filename="/root/.telco/sims.cfg";
FILE *f = fopen(filename,"r");
if (!f) {  printf("Load File %s failed\n",filename); return -2;   }
char buf[1024];
while( fgets(buf,sizeof(buf),f) ) {
  uchar *c=buf;
  uchar *iccid = get_word(&c);
  if (strcmp(iccid,_iccid)==0) { // found !
    //printf("FOUND! <%s>\n",c);
   strNcpy( j->ICCID, iccid );
   sscanf( get_wordl(&c,4) ,"%04X", &j->spi); sscanf( get_wordl(&c,2) ,"%02X", &j->kic); sscanf( get_wordl(&c,2) ,"%04X", &j->kid);
   //printf("Line2\n");
   hexstr2bin( j->tar, get_wordl(&c,3),-1);  hexstr2bin( j->KIC, get_wordl(&c,24*2),-1); hexstr2bin( j->KID, get_wordl(&c,24*2),-1);
   //printf("Line3\n");
   uchar *s = get_wordl(&c,24); strNcpy(j->MSISDN,s);
          s = get_wordl(&c,24); strNcpy(j->IMSI,s);
   sscanf( get_wordl(&c,4) ,"%04X", &j->counter);
   fclose(f);
   //printf("NOW - update counter\n");
   mkdir("/root/.telco",S_IRWXU); mkdir("/root/.telco/counter",S_IRWXU); // ensure dir exists
  // Now - update counter - if any
   sprintf(buf,"/root/.telco/counter/%s",j->ICCID);
   f = fopen(buf,"r");
   if (f) {
      if (fgets(buf,sizeof(buf),f)) if (sscanf(buf,"%x",&j->counter)) {
           //printf("CounterUpdated: %d, hex:%x\n",j->counter,j->counter);
           }
      fclose(f);
       }
    j->saveCounter = cardJobSaveCounter;
    //exit(1222);
    return 1; // OK - config loaded
    }
  }
fclose(f);
printf("DataFor ICCID %s not found\n",_iccid);
return 0;
}
示例#10
0
void cardJobSetup(struct _cardJob *j,
                     int spi, int kic, int kid,  // profile data
                     uchar *ICCID,
                     uchar *KIC, uchar *KID, // personal data
                     int counter) {
if (j==0) j = &cardJob; /// default global
//printf("j=%x\n",j);
j->spi = spi; j->kic = kic; j->kid = kid;
strNcpy(j->ICCID,ICCID);
hexstr2bin(j->KID,KID,-1); // copy pair?
hexstr2bin(j->KIC,KIC,-1);
j->counter = counter;
}
示例#11
0
int gmodem_sim800_wget(gmodem *g,char *url,char *buf,int size) {
int csq = 0;
char ip[20]; buf[0]=0;
gmodem_logf(g,3,"sim800.wget:check GSM coverage");
if (gmodem_csq(g,&csq)<=0) return gmodem_errorf(g,-3,"GSM not connected");
gmodem_logf(g,3,"sim800.wget:check GPRS bearer");
if (gmodem_sim800_getip(g,ip)>0) {
   gmodem_logf(g,3,"sim800.wget: modem has IP address: %s",ip);
   } else {
   char *apn = gmodem_get_default_apn(g);
   if (gmodem_sim800_ip_attach(g,apn )<=0) return 0;
   }
//char buf[300]; int len=sizeof(buf);
gmodem_logf(g,3,"sim800.wget ready for http");
int code = gmodem_sim800_http_connect(g,url,60); if (code<=0) return code; // gmodem_errorf(g,-3,"wget http_connect failed");
int len = size-1;
  if( len > g->http_len) len=g->http_len;
int ok = gmodem_sim800_http_read(g,buf,len); // read one block
if (ok<=0) return -1;
strNcpy(g->out,buf); // copy to state
return 1;
}
示例#12
0
文件: pstream.c 项目: csound/csound
static int32_t pvsfreadset_(CSOUND *csound, PVSFREAD *p, int32_t stringname)
{
    PVOCEX_MEMFILE  pp;
    uint32   N;
    char            pvfilnam[MAXNAME];

    if (stringname) strNcpy(pvfilnam, ((STRINGDAT*)p->ifilno)->data, MAXNAME-1);
    else if (csound->ISSTRCOD(*p->ifilno))
      strNcpy(pvfilnam, get_arg_string(csound, *p->ifilno), MAXNAME-1);
    else csound->strarg2name(csound, pvfilnam, p->ifilno, "pvoc.", 0);

    if (UNLIKELY(PVOCEX_LoadFile(csound, pvfilnam, &pp) != 0)) {
      return csound->InitError(csound, Str("Failed to load PVOC-EX file"));
    }
    p->ptr = 0;
    p->overlap = pp.overlap;
    p->winsize = pp.winsize;
    p->fftsize = pp.fftsize;
    p->wintype = pp.wintype;
    p->format  = pp.format;
    p->chans   = pp.chans;
    p->nframes = pp.nframes;
    p->arate   = csound->esr / (MYFLT) pp.overlap;
    p->membase = (float*) pp.data;

    if (UNLIKELY(p->overlap < (int32_t)CS_KSMPS || p->overlap < 10))
      return csound->InitError(csound, Str("Sliding version not yet available"));
    if (UNLIKELY(p->nframes <= 0))
      return csound->InitError(csound, Str("pvsfread: file is empty!\n"));
    /* special case if only one frame - it is an impulse response */
    if (UNLIKELY(p->nframes == 1))
      return csound->InitError(csound, Str("pvsfread: file has only one frame "
                              "(= impulse response).\n"));
    if (UNLIKELY(p->overlap < (int32_t)CS_KSMPS))
      return csound->InitError(csound, Str("pvsfread: analysis frame overlap "
                              "must be >= ksmps\n"));
    p->blockalign = (p->fftsize+2) * p->chans;
    if (UNLIKELY((*p->ichan) >= p->chans))
      return csound->InitError(csound, Str("pvsfread: ichan value exceeds "
                              "file channel count.\n"));
    if (UNLIKELY((int32_t) (*p->ichan) < 0))
      return csound->InitError(csound,
                               Str("pvsfread: ichan cannot be negative.\n"));

    N = p->fftsize;
    /* setup output signal */
    csound->AuxAlloc(csound, (N + 2) * sizeof(float), &p->fout->frame);
    /* init sig with first frame from file,
       regardless (always zero amps, but with bin freqs) */
    p->chanoffset = (int32_t) MYFLT2LRND(*p->ichan) * (N + 2);
    memcpy((float *) p->fout->frame.auxp,               /* RWD MUST be 32bit */
           (float *) pp.data + (int32_t) p->chanoffset,    /* RWD MUST be 32bit */
           (size_t) ((int32_t) (N + 2) * (int32_t) sizeof(float)));
    p->membase += p->blockalign;  /* move to 2nd frame in file, as startpoint */
    p->nframes--;
    p->fout->N           =  N;
    p->fout->overlap = p->overlap;
    p->fout->winsize = p->winsize;
    p->fout->wintype = p->wintype;
    p->fout->format  = p->format;
    p->fout->framecount = 1;
    p->lastframe = 0;
    return OK;
}
示例#13
0
static int sendrecv_eap(RADIUS_PACKET *rep)
{
	RADIUS_PACKET *req = NULL;
	VALUE_PAIR *vp, *vpnext;
	int tried_eap_md5 = 0;

	/*
	 *	Keep a copy of the the User-Password attribute.
	 */
	if ((vp = pairfind(rep->vps, ATTRIBUTE_EAP_MD5_PASSWORD)) != NULL) {
		strNcpy(password, (char *)vp->strvalue, sizeof(vp->strvalue));

	} else 	if ((vp = pairfind(rep->vps, PW_PASSWORD)) != NULL) {
		strNcpy(password, (char *)vp->strvalue, sizeof(vp->strvalue));
		/*
		 *	Otherwise keep a copy of the CHAP-Password attribute.
		 */
	} else if ((vp = pairfind(rep->vps, PW_CHAP_PASSWORD)) != NULL) {
		strNcpy(password, (char *)vp->strvalue, sizeof(vp->strvalue));
	} else {
		*password = '******';
	}

 again:
	rep->id++;

	printf("\n+++> About to send encoded packet:\n");
	vp_printlist(stdout, rep->vps);

	/*
	 * if there are EAP types, encode them into an EAP-Message
	 *
	 */
	map_eap_types(rep);

	/*
	 *  Fix up Digest-Attributes issues
	 */
	for (vp = rep->vps; vp != NULL; vp = vp->next) {
		switch (vp->attribute) {
		default:
			break;

		case PW_DIGEST_REALM:
		case PW_DIGEST_NONCE:
		case PW_DIGEST_METHOD:
		case PW_DIGEST_URI:
		case PW_DIGEST_QOP:
		case PW_DIGEST_ALGORITHM:
		case PW_DIGEST_BODY_DIGEST:
		case PW_DIGEST_CNONCE:
		case PW_DIGEST_NONCE_COUNT:
		case PW_DIGEST_USER_NAME:
			/* overlapping! */
			memmove(&vp->strvalue[2], &vp->strvalue[0], vp->length);
			vp->strvalue[0] = vp->attribute - PW_DIGEST_REALM + 1;
			vp->length += 2;
			vp->strvalue[1] = vp->length;
			vp->attribute = PW_DIGEST_ATTRIBUTES;
			break;
		}
	}

	/*
	 *	If we've already sent a packet, free up the old
	 *	one, and ensure that the next packet has a unique
	 *	ID and authentication vector.
	 */
	if (rep->data) {
		free(rep->data);
		rep->data = NULL;
	}

	librad_md5_calc(rep->vector, rep->vector,
			sizeof(rep->vector));

	if (*password != '\0') {
		if ((vp = pairfind(rep->vps, PW_PASSWORD)) != NULL) {
			strNcpy((char *)vp->strvalue, password, strlen(password) + 1);
			vp->length = strlen(password);

		} else if ((vp = pairfind(rep->vps, PW_CHAP_PASSWORD)) != NULL) {
			strNcpy((char *)vp->strvalue, password, strlen(password) + 1);
			vp->length = strlen(password);

			rad_chap_encode(rep, (char *) vp->strvalue, rep->id, vp);
			vp->length = 17;
		}
	} /* there WAS a password */

	/* send the response, wait for the next request */
	send_packet(rep, &req);

	/* okay got back the packet, go and decode the EAP-Message. */
	unmap_eap_types(req);

	printf("<+++ EAP decoded packet:\n");
	vp_printlist(stdout, req->vps);

	/* now look for the code type. */
	for (vp = req->vps; vp != NULL; vp = vpnext) {
		vpnext = vp->next;

		switch (vp->attribute) {
		default:
			break;

		case ATTRIBUTE_EAP_BASE+PW_EAP_MD5:
			if(respond_eap_md5(req, rep) && tried_eap_md5 < 3)
			{
				tried_eap_md5++;
				goto again;
			}
			break;

		case ATTRIBUTE_EAP_BASE+PW_EAP_SIM:
			if(respond_eap_sim(req, rep))
			{
				goto again;
			}
			break;
		}
	}

	return 1;
}
示例#14
0
/*
 *	Calculate/check digest, and decode radius attributes.
 */
int rad_decode(RADIUS_PACKET *packet, RADIUS_PACKET *original,
	       const char *secret)
{
	DICT_ATTR		*attr;
	uint32_t		lvalue;
	uint32_t		vendorcode;
	VALUE_PAIR		**tail;
	VALUE_PAIR		*pair;
	uint8_t			*ptr;
	int			length;
	int			attribute;
	int			attrlen;
	int			vendorlen;
	radius_packet_t		*hdr;

	hdr = (radius_packet_t *)packet->data;

	/*
	 *	Before we allocate memory for the attributes, do more
	 *	sanity checking.
	 */
	ptr = hdr->data;
	length = packet->data_len - AUTH_HDR_LEN;
	while (length > 0) {
		uint8_t	msg_auth_vector[AUTH_VECTOR_LEN];
		uint8_t calc_auth_vector[AUTH_VECTOR_LEN];

		attrlen = ptr[1];

		switch (ptr[0]) {
		default:	/* don't do anything. */
			break;

			/*
			 *	Note that more than one Message-Authenticator
			 *	attribute is invalid.
			 */
		case PW_MESSAGE_AUTHENTICATOR:
			memcpy(msg_auth_vector, &ptr[2], sizeof(msg_auth_vector));
			memset(&ptr[2], 0, AUTH_VECTOR_LEN);

			switch (packet->code) {
			default:
			  break;

			case PW_AUTHENTICATION_ACK:
			case PW_AUTHENTICATION_REJECT:
			case PW_ACCESS_CHALLENGE:
			  if (original) {
				  memcpy(packet->data + 4, original->vector, AUTH_VECTOR_LEN);
			  }
			  break;
			}

			lrad_hmac_md5(packet->data, packet->data_len,
				      secret, strlen(secret), calc_auth_vector);
			if (memcmp(calc_auth_vector, msg_auth_vector,
				    sizeof(calc_auth_vector)) != 0) {
				char buffer[32];
				librad_log("Received packet from %s with invalid Message-Authenticator!  (Shared secret is incorrect.)",
					   ip_ntoa(buffer, packet->src_ipaddr));
				return 1;
			} /* else the message authenticator was good */

			/*
			 *	Reinitialize Authenticators.
			 */
			memcpy(&ptr[2], msg_auth_vector, AUTH_VECTOR_LEN);
			memcpy(packet->data + 4, packet->vector, AUTH_VECTOR_LEN);
			break;
		} /* switch over the attributes */

		ptr += attrlen;
		length -= attrlen;
	} /* loop over the packet, sanity checking the attributes */

	/*
	 *	Calculate and/or verify digest.
	 */
	switch(packet->code) {
		int rcode;

		case PW_AUTHENTICATION_REQUEST:
		case PW_STATUS_SERVER:
		case PW_DISCONNECT_REQUEST:
			/*
			 *	The authentication vector is random
			 *	nonsense, invented by the client.
			 */
			break;

		case PW_ACCOUNTING_REQUEST:
			if (calc_acctdigest(packet, secret) > 1) {
				char buffer[32];
				librad_log("Received Accounting-Request packet "
				    "from %s with invalid signature!  (Shared secret is incorrect.)",
				    ip_ntoa(buffer, packet->src_ipaddr));
				return 1;
			}
			break;

			/* Verify the reply digest */
		case PW_AUTHENTICATION_ACK:
		case PW_AUTHENTICATION_REJECT:
		case PW_ACCOUNTING_RESPONSE:
			rcode = calc_replydigest(packet, original, secret);
			if (rcode > 1) {
				char buffer[32];
				librad_log("Received %s packet "
					   "from %s with invalid signature (err=%d)!  (Shared secret is incorrect.)",
					   packet_codes[packet->code],
					   ip_ntoa(buffer, packet->src_ipaddr),
					   rcode);
				return 1;
			}
		  break;
	}

	/*
	 *	Extract attribute-value pairs
	 */
	ptr = hdr->data;
	length = packet->data_len - AUTH_HDR_LEN;
	packet->vps = NULL;
	tail = &packet->vps;

	vendorcode = 0;
	vendorlen  = 0;

	while(length > 0) {
		if (vendorlen > 0) {
			attribute = *ptr++ | (vendorcode << 16);
			attrlen   = *ptr++;
		} else {
			attribute = *ptr++;
			attrlen   = *ptr++;
		}

		attrlen -= 2;
		length  -= 2;

		/*
		 *	This could be a Vendor-Specific attribute.
		 *
		 */
		if ((vendorlen <= 0) &&
		    (attribute == PW_VENDOR_SPECIFIC) && 
		    (attrlen > 6)) {
			memcpy(&lvalue, ptr, 4);
			vendorcode = ntohl(lvalue);
			if (vendorcode != 0) {

				if (vendorcode == VENDORPEC_USR) {
					ptr += 4;
					memcpy(&lvalue, ptr, 4);
					/*printf("received USR %04x\n", ntohl(lvalue));*/
					attribute = (ntohl(lvalue) & 0xFFFF) |
							(vendorcode << 16);
					ptr += 4;
					attrlen -= 8;
					length -= 8;

				} else {
					ptr += 4;
					vendorlen = attrlen - 4;
					attribute = *ptr++ | (vendorcode << 16);
					attrlen   = *ptr++;
					attrlen -= 2;
					length -= 6;
				}
			}
			/*
			 *  Else the vendor wasn't found...
			 */
		}

		/*
		 *	FIXME: should we us paircreate() ?
		 */
		if ((pair = malloc(sizeof(VALUE_PAIR))) == NULL) {
			pairfree(&packet->vps);
			librad_log("out of memory");
			errno = ENOMEM;
			return -1;
		}
		
		memset(pair, 0, sizeof(VALUE_PAIR));
		if ((attr = dict_attrbyvalue(attribute)) == NULL) {
			snprintf(pair->name, sizeof(pair->name), "Attr-%d", attribute);
			pair->type = PW_TYPE_OCTETS;
		} else {
			strcpy(pair->name, attr->name);
			pair->type = attr->type;
			pair->flags = attr->flags;
		}
		pair->attribute = attribute;
		pair->length = attrlen;
		pair->operator = T_OP_EQ;
		pair->next = NULL;
		
		switch (pair->type) {
			
		case PW_TYPE_OCTETS:
		case PW_TYPE_ABINARY:
		case PW_TYPE_STRING:
			if (pair->flags.has_tag &&
			    pair->type == PW_TYPE_STRING) {
				int offset = 0;

				if ((pair->length > 0) && TAG_VALID(*ptr)) {
					pair->flags.tag = *ptr;
					pair->length--;
					offset = 1;
				} else if (pair->flags.encrypt == FLAG_ENCRYPT_TUNNEL_PASSWORD) {
					/*
					 * from RFC2868 - 3.5.  Tunnel-Password
					 * If the value of the Tag field is greater than
					 * 0x00 and less than or equal to 0x1F, it SHOULD
					 * be interpreted as indicating which tunnel
					 * (of several alternatives) this attribute pertains;
					 * otherwise, the Tag field SHOULD be ignored.
					 */
					pair->flags.tag = 0x00;
					if (pair->length > 0) pair->length--;
					offset = 1;
				} else {
				       pair->flags.tag = 0x00;
				}

				/*
				 *	pair->length may be zero here...
				 */
				memcpy(pair->strvalue, ptr + offset,
				       pair->length);
			} else {
				/* attrlen always < MAX_STRING_LEN */
				memcpy(pair->strvalue, ptr, attrlen);
			        pair->flags.tag = 0;
			}

			/*
			 *  FIXME: HACK for non-updated dictionaries.
			 *  REMOVE in a future release.
			 */
			if ((strcmp(pair->name, "Ascend-Send-Secret") == 0) ||
			    (strcmp(pair->name, "Ascend-Receive-Secret") == 0)) {
				pair->flags.encrypt = FLAG_ENCRYPT_ASCEND_SECRET;
			}
			if (pair->attribute == PW_USER_PASSWORD) {
				pair->flags.encrypt = FLAG_ENCRYPT_USER_PASSWORD;
			}

			/*
			 *	Decrypt passwords here.
			 */
			switch (pair->flags.encrypt) {
			default:
				break;

				/*
				 *  User-Password
				 */
			case FLAG_ENCRYPT_USER_PASSWORD:
				if (original) {
					rad_pwdecode((char *)pair->strvalue,
						     pair->length, secret,
						     (char *)original->vector);
				} else {
					rad_pwdecode((char *)pair->strvalue,
						     pair->length, secret,
						     (char *)packet->vector);
				}
				if (pair->attribute == PW_USER_PASSWORD) {
					pair->length = strlen(pair->strvalue);
				}
				break;

				/*
				 *  Tunnel-Password
				 */
			case FLAG_ENCRYPT_TUNNEL_PASSWORD:
				if (!original) {
					librad_log("ERROR: Tunnel-Password attribute in request: Cannot decrypt it.");
					return -1;
				}
			        rad_tunnel_pwdecode((char *)pair->strvalue,
						    &pair->length, 
						    secret,
						    (char *)original->vector);
				break;

				/*
				 *  Ascend-Send-Secret
				 *  Ascend-Receive-Secret
				 */
			case FLAG_ENCRYPT_ASCEND_SECRET:
				{
					uint8_t my_digest[AUTH_VECTOR_LEN];
					make_secret(my_digest,
						    original->vector,
						    secret, ptr);
					memcpy(pair->strvalue, my_digest,
					       AUTH_VECTOR_LEN );
					pair->strvalue[AUTH_VECTOR_LEN] = '\0';
					pair->length = strlen(pair->strvalue);
				}
				break;
			} /* switch over encryption flags */
			break;	/* from octets/string/abinary */
			
		case PW_TYPE_INTEGER:
		case PW_TYPE_DATE:
		case PW_TYPE_IPADDR:
			/*
			 *	Check for RFC compliance.  If the
			 *	attribute isn't compliant, turn it
			 *	into a string of raw octets.
			 *
			 *	Also set the lvalue to something
			 *	which should never match anything.
			 */
			if (attrlen != 4) {
				pair->type = PW_TYPE_OCTETS;
				memcpy(pair->strvalue, ptr, attrlen);
				pair->lvalue = 0xbad1bad1;
				break;
			}

      			memcpy(&lvalue, ptr, 4);

			if (attr->type != PW_TYPE_IPADDR) {
				pair->lvalue = ntohl(lvalue);
			} else {
				 /*
				  *  It's an IP address, keep it in network
				  *  byte order, and put the ASCII IP
				  *  address or host name into the string
				  *  value.
				  */
				pair->lvalue = lvalue;
				ip_ntoa(pair->strvalue, pair->lvalue);
			}

			/*
			 *  Only PW_TYPE_INTEGER should have tags.
			 */
			if (pair->flags.has_tag &&
			    pair->type == PW_TYPE_INTEGER) {
			        pair->flags.tag = (pair->lvalue >> 24) & 0xff;
				pair->lvalue &= 0x00ffffff;
			}

			if (attr->type == PW_TYPE_INTEGER) {
				DICT_VALUE *dval;
				dval = dict_valbyattr(pair->attribute,
						      pair->lvalue);
				if (dval) {
					strNcpy(pair->strvalue,
						dval->name,
						sizeof(pair->strvalue));
				}
			}
			break;
			
		default:
			DEBUG("    %s (Unknown Type %d)\n",
			      attr->name,attr->type);
			free(pair);
			pair = NULL;
			break;
		}
		
		if (pair) {
			debug_pair(pair);
			*tail = pair;
			tail = &pair->next;
		}

		ptr += attrlen;
		length -= attrlen;
		if (vendorlen > 0) vendorlen -= (attrlen + 2);
	}
示例#15
0
/*
 *	Internal function to cut down on duplicated code.
 *
 *	Returns -1 on failure, 0 on no failure.  returnrealm
 *	is NULL on don't proxy, realm otherwise.
 */
static int check_for_realm(void *instance, REQUEST *request, REALM **returnrealm)
{
	char namebuf[MAX_STRING_LEN];
	char *username;
	char *realmname = NULL;
	char *ptr;
	VALUE_PAIR *vp;
	REALM *realm;

        struct realm_config_t *inst = instance;

	/* initiate returnrealm */
	*returnrealm = NULL;

	/*
	 *	If the request has a proxy entry, then it's a proxy
	 *	reply, and we're walking through the module list again.
	 *
	 *	In that case, don't bother trying to proxy the request
	 *	again.
	 *
	 *	Also, if there's no User-Name attribute, we can't
	 *	proxy it, either.
	 */
	if ((request->proxy != NULL) ||
	    (request->username == NULL)) {
		DEBUG2("    rlm_realm: Proxy reply, or no User-Name.  Ignoring.");
		return 0;
	}

	/*
	 *      Check for 'Realm' attribute.  If it exists, then we've proxied
	 *      it already ( via another rlm_realm instance ) and should return.
	 */

	if ( (vp = pairfind(request->packet->vps, PW_REALM)) != NULL ) {
	        DEBUG2("    rlm_realm: Request already proxied.  Ignoring.");
		return 0;
	}

	/*
	 *	We will be modifing this later, so we want our own copy
	 *	of it.
	 */
	strNcpy(namebuf, (char *)request->username->strvalue, sizeof(namebuf));
	username = namebuf;

	switch(inst->format)
	{

	case REALM_FORMAT_SUFFIX:

	  /* DEBUG2("  rlm_realm: Checking for suffix after \"%c\"", inst->delim[0]); */
		realmname = strrchr(username, inst->delim[0]);
		if (realmname) {
			*realmname = '\0';
			realmname++;
		}
		break;

	case REALM_FORMAT_PREFIX:

		/* DEBUG2("  rlm_realm: Checking for prefix before \"%c\"", inst->delim[0]); */

		ptr = strchr(username, inst->delim[0]);
		if (ptr) {
			*ptr = '\0';
		     ptr++;
		     realmname = username;
		     username = ptr;
		}
		break;

	default:
		realmname = NULL;
		break;
	}

	/*
	 *	Print out excruciatingly descriptive debugging messages
	 *	for the people who find it too difficult to think about
	 *	what's going on.
	 */
	if (realmname) {
		DEBUG2("    rlm_realm: Looking up realm \"%s\" for User-Name = \"%s\"",
		       realmname, request->username->strvalue);
	} else {
		if( inst->ignore_null ) {
			DEBUG2("    rlm_realm: No '%c' in User-Name = \"%s\", skipping NULL due to config.",
			inst->delim[0], request->username->strvalue);
			return 0;
		}
		DEBUG2("    rlm_realm: No '%c' in User-Name = \"%s\", looking up realm NULL",
		       inst->delim[0], request->username->strvalue);
	}

	/*
	 *	Allow DEFAULT realms unless told not to.
	 */
	realm = realm_find(realmname, (request->packet->code == PW_ACCOUNTING_REQUEST));
	if (!realm) {
		DEBUG2("    rlm_realm: No such realm \"%s\"",
		       (realmname == NULL) ? "NULL" : realmname);
		return 0;
	}
	if( inst->ignore_default &&
	    (strcmp(realm->realm, "DEFAULT")) == 0) {
		DEBUG2("    rlm_realm: Found DEFAULT, but skipping due to config.");
		return 0;
	}


	DEBUG2("    rlm_realm: Found realm \"%s\"", realm->realm);

	/*
	 *	If we've been told to strip the realm off, then do so.
	 */
	if (realm->striprealm) {
		/*
		 *	Create the Stripped-User-Name attribute, if it
		 *	doesn't exist.
		 *
		 */
		if (request->username->attribute != PW_STRIPPED_USER_NAME) {
			vp = paircreate(PW_STRIPPED_USER_NAME, PW_TYPE_STRING);
			if (!vp) {
				radlog(L_ERR|L_CONS, "no memory");
				return -1;
			}
			pairadd(&request->packet->vps, vp);
			DEBUG2("    rlm_realm: Adding Stripped-User-Name = \"%s\"", username);
		} else {
			vp = request->username;
			DEBUG2("    rlm_realm: Setting Stripped-User-Name = \"%s\"", username);
		}

		strcpy(vp->strvalue, username);
		vp->length = strlen((char *)vp->strvalue);
		request->username = vp;
	}

	DEBUG2("    rlm_realm: Proxying request from user %s to realm %s",
	       username, realm->realm);

	/*
	 *	Add the realm name to the request.
	 */
	pairadd(&request->packet->vps, pairmake("Realm", realm->realm,
						T_OP_EQ));
	DEBUG2("    rlm_realm: Adding Realm = \"%s\"", realm->realm);

	/*
	 *	Figure out what to do with the request.
	 */
	switch (request->packet->code) {
	default:
		DEBUG2("    rlm_realm: Unknown packet code %d\n",
		       request->packet->code);
		return 0;		/* don't do anything */

		/*
		 *	Perhaps accounting proxying was turned off.
		 */
	case PW_ACCOUNTING_REQUEST:
		if (realm->acct_ipaddr == htonl(INADDR_NONE)) {
			DEBUG2("    rlm_realm: Accounting realm is LOCAL.");
			return 0;
		}

		if (realm->acct_port == 0) {
			DEBUG2("    rlm_realm: acct_port is not set.  Proxy cancelled.");
			return 0;
		}
		break;

		/*
		 *	Perhaps authentication proxying was turned off.
		 */
	case PW_AUTHENTICATION_REQUEST:
		if (realm->ipaddr == htonl(INADDR_NONE)) {
			DEBUG2("    rlm_realm: Authentication realm is LOCAL.");
			return 0;
		}

		if (realm->auth_port == 0) {
			DEBUG2("    rlm_realm: auth_port is not set.  Proxy cancelled.");
			return 0;
		}
		break;
	}

	/*
	 *      If this request has arrived from another freeradius server
	 *      that has already proxied the request, we don't need to do
	 *      it again.
	 */
	for (vp = request->packet->vps; vp; vp = vp->next) {
		if (vp->attribute == PW_FREERADIUS_PROXIED_TO) {
			if (request->packet->code == PW_AUTHENTICATION_REQUEST &&
			    vp->lvalue == realm->ipaddr) {
				DEBUG2("    rlm_realm: Request not proxied due to Freeradius-Proxied-To");
				return 0;
			}
			if (request->packet->code == PW_ACCOUNTING_REQUEST &&
			    vp->lvalue == realm->acct_ipaddr) {
				DEBUG2("    rlm_realm: Request not proxied due to Freeradius-Proxied-To");
				return 0;
			}
		}
        }

	/*
	 *	We got this far, which means we have a realm, set returnrealm
	 */
	*returnrealm = realm;
	return 0;
}
示例#16
0
static int sqlcounter_expand(char *out, int outlen, const char *fmt, void *instance)
{
	rlm_sqlcounter_t *data = (rlm_sqlcounter_t *) instance;
	int c,freespace;
	const char *p;
	char *q;
	char tmpdt[40]; /* For temporary storing of dates */
	int openbraces=0;

	q = out;
	for (p = fmt; *p ; p++) {
	/* Calculate freespace in output */
	freespace = outlen - (q - out);
		if (freespace <= 1)
			break;
		c = *p;
		if ((c != '%') && (c != '$') && (c != '\\')) {
			/*
			 * We check if we're inside an open brace.  If we are
			 * then we assume this brace is NOT literal, but is
			 * a closing brace and apply it
			 */
			if((c == '}') && openbraces) {
				openbraces--;
				continue;
			}
			*q++ = *p;
			continue;
		}
		if (*++p == '\0') break;
		if (c == '\\') switch(*p) {
			case '\\':
				*q++ = *p;
				break;
			case 't':
				*q++ = '\t';
				break;
			case 'n':
				*q++ = '\n';
				break;
			default:
				*q++ = c;
				*q++ = *p;
				break;

		} else if (c == '%') switch(*p) {

			case '%':
				*q++ = *p;
			case 'b': /* last_reset */
				snprintf(tmpdt, sizeof(tmpdt), "%lu", data->last_reset);
				strNcpy(q, tmpdt, freespace);
				q += strlen(q);
				break;
			case 'e': /* reset_time */
				snprintf(tmpdt, sizeof(tmpdt), "%lu", data->reset_time);
				strNcpy(q, tmpdt, freespace);
				q += strlen(q);
				break;
			case 'k': /* Key Name */
				strNcpy(q, data->key_name, freespace);
				q += strlen(q);
				break;
			case 'S': /* SQL module instance */
				strNcpy(q, data->sqlmod_inst, freespace);
				q += strlen(q);
				break;
			default:
				*q++ = '%';
				*q++ = *p;
				break;
		}
	}
	*q = '\0';

	DEBUG2("sqlcounter_expand:  '%s'", out);

	return strlen(out);
}
示例#17
0
文件: winEPS.c 项目: csound/csound
void PS_MakeGraph(CSOUND *csound, WINDAT *wdptr, const char *name)
{
    winEPS_globals_t  *pp;
    char      *filenam;
    char      pathnam[1024];
    char      *t;
    time_t    lt;
    OPARMS oparms;
     csound->GetOParms(csound, &oparms);
     IGN(wdptr);
     IGN(name);

    if (csound->winEPS_globals != NULL)
      return;
    csound->winEPS_globals = csound->Calloc(csound, sizeof(winEPS_globals_t));
    pp = (winEPS_globals_t *) csound->winEPS_globals;

    filenam = oparms.outfilename;
    if (filenam == NULL)
      filenam = "test";     /* O.outfilename not set yet */

    /*  If sound output is being piped directly to the DAC, then */
    /*  there is no PS output, (psFileOK remains 0),             */
    /*  otherwise open an encapsulated PostScript output file    */
    /*  with a name related to the sound file's name.            */
    /*                                                           */
    /*  The PS file is located in the same directory as the      */
    /*  sound file, and has the name of the sound file with the  */
    /*  extension ``.eps'' appended.                             */
    /*                                                           */

    /**
     *  Remove extension from sound-file and add ".eps"
     */
    strNcpy(pathnam, filenam, 1024); //pathnam[1023] = '\0';
    t = strrchr(pathnam, '.');
    if (t != NULL) *t = '\0';
    strlcat(pathnam, ".eps", 1024);
    pp->psfd = csound->FileOpen2(csound, &(pp->psFile), CSFILE_STD, pathnam,
                                   "w", "SFDIR", CSFTYPE_POSTSCRIPT, 0);
    if (UNLIKELY(pp->psfd == NULL)) {
      csound->Message(csound, Str("** Warning **  PostScript file %s "
                                  "cannot be opened\n"), pathnam);
      csound->winEPS_globals = NULL;
      csound->Free(csound, (void *)pp);
      return;
    }
    csound->Message(csound, Str("\n PostScript graphs written to file %s\n\n"),
                            pathnam);
    /**
     *  Get the current time and date
     */
    lt = time(NULL);
#ifndef LINUX
    {
      struct tm *date_ptr;
      char      *date;
      date_ptr = localtime(&lt);
      date = asctime(date_ptr);
      t = pp->ps_date;
      while (*date != '\n')
        *t++ = *date++;
      *t = '\0';
    }
#else
    /* avoid use of non-reentrant functions */
    {
      struct tm tmp1;
      memset(&tmp1, 0, sizeof(struct tm));
      localtime_r(&lt, &tmp1);
      asctime_r(&tmp1, &(pp->ps_date[0]));
    }
#endif
    /**
     *  Print PostScript file Header
     *  Place every plot on a new page.
     */
    fprintf(pp->psFile, "%s \n", "%!PS-Adobe-2.0");
    fprintf(pp->psFile, "%s \n", "%%Creator: Csound");
    fprintf(pp->psFile, "%s %s \n", "%%CreationDate:", pp->ps_date);
    fprintf(pp->psFile, "%s \n", "%%Pages: (atend)");
    fprintf(pp->psFile, "%s \n", "%%PageOrder: Ascend");
    fprintf(pp->psFile, "%s \n", "%%BoundingBox: 010 010 540 700");
    fprintf(pp->psFile, "%s \n", "%%Orientation: Portrait");
    fprintf(pp->psFile, "%s \n", "%%EndComments");
    fprintf(pp->psFile, "%s \n", "   ");
}
示例#18
0
/*
 *	Find a module instance.
 */
module_instance_t *find_module_instance(const char *instname)
{
	CONF_SECTION *cs, *inst_cs;
	const char *name1, *name2;
	module_instance_t *node, **last;
	char module_name[256];

	/*
	 *	Look through the global module instance list for the
	 *	named module.
	 */
	last = &module_instance_list;
	for (node = module_instance_list; node != NULL; node = node->next) {
		/*
		 *	Found the named instance.  Return it.
		 */
		if (strcmp(node->name, instname) == 0)
			return node;

		/*
		 *	Keep a pointer to the last entry to update...
		 */
		last = &node->next;
	}

	/*
	 *	Instance doesn't exist yet. Try to find the
	 *	corresponding configuration section and create it.
	 */

	/*
	 *	Look for the 'modules' configuration section.
	 */
	cs = cf_section_find("modules");
	if (cs == NULL) {
		radlog(L_ERR|L_CONS, "ERROR: Cannot find a 'modules' section in the configuration file.\n");
		return NULL;
	}

	/*
	 *	Module instances are declared in the modules{} block
	 *	and referenced later by their name, which is the
	 *	name2 from the config section, or name1 if there was
	 *	no name2.
	 */
	name1 = name2 = NULL;
	for(inst_cs=cf_subsection_find_next(cs, NULL, NULL); 
			inst_cs != NULL;
			inst_cs=cf_subsection_find_next(cs, inst_cs, NULL)) {
		name1 = cf_section_name1(inst_cs);
		name2 = cf_section_name2(inst_cs);
		if ( (name2 && !strcmp(name2, instname)) ||
		     (!name2 && !strcmp(name1, instname)) )
			break;
	}
	if (inst_cs == NULL) {
		radlog(L_ERR|L_CONS, "ERROR: Cannot find a configuration entry for module \"%s\".\n", instname);
		return NULL;
	}

	/*
	 *	Found the configuration entry.
	 */
	node = rad_malloc(sizeof(*node));
	node->next = NULL;
	node->insthandle = NULL;
	
	/*
	 *	Link to the module by name: rlm_FOO-major.minor
	 */
	if (strncmp(name1, "rlm_", 4)) {
#if 0
		snprintf(module_name, sizeof(module_name), "rlm_%s-%d.%d",
			 name1, RADIUSD_MAJOR_VERSION, RADIUSD_MINOR_VERSION);
#else
		snprintf(module_name, sizeof(module_name), "rlm_%s",
			 name1);
#endif
	} else {
		strNcpy(module_name, name1, sizeof(module_name));

	}

	/*
	 *  FIXME: "radiusd.conf" is wrong here; must find cf filename
	 */
	node->entry = linkto_module(module_name, "radiusd.conf",
				    cf_section_lineno(inst_cs));
	if (!node->entry) {
		free(node);
		/* linkto_module logs any errors */
		return NULL;
	}
	
	/*
	 *	Call the module's instantiation routine.
	 */
	if ((node->entry->module->instantiate) &&
	    ((node->entry->module->instantiate)(inst_cs,
			&node->insthandle) < 0)) {
		radlog(L_ERR|L_CONS,
				"radiusd.conf[%d]: %s: Module instantiation failed.\n",
				cf_section_lineno(inst_cs), instname);
		free(node);
		return NULL;
	}

	/*
	 *	We're done.  Fill in the rest of the data structure,
	 *	and link it to the module instance list.
	 */
	strNcpy(node->name, instname, sizeof(node->name));

#if HAVE_PTHREAD_H
	/*
	 *	If we're threaded, check if the module is thread-safe.
	 *
	 *	If it isn't, we create a mutex.
	 */
	if ((node->entry->module->type & RLM_TYPE_THREAD_UNSAFE) != 0) {
		node->mutex = (pthread_mutex_t *) rad_malloc(sizeof(pthread_mutex_t));
		/*
		 *	Initialize the mutex.
		 */
		pthread_mutex_init(node->mutex, NULL);
	} else {
		/*
		 *	The module is thread-safe.  Don't give it a mutex.
		 */
		node->mutex = NULL;
	}

#endif	
	*last = node;

	DEBUG("Module: Instantiated %s (%s) ", name1, node->name);
	
	return node;
}
示例#19
0
/*
 *	Find a module on disk or in memory, and link to it.
 */
static module_list_t *linkto_module(const char *module_name,
		const char *cffilename, int cflineno)
{
	module_list_t *node;
	lt_dlhandle handle;
	char module_struct[256];
	char *p;

	/*
	 *	Look through the global module library list for the
	 *	named module.
	 */
	for (node = module_list; node != NULL; node = node->next) {
		/*
		 *	Found the named module.  Return it.
		 */
		if (strcmp(node->name, module_name) == 0)
			return node;

	}

	/*
	 *	Keep the handle around so we can dlclose() it.
	 */
	handle = lt_dlopenext(module_name);
	if (handle == NULL) {
		radlog(L_ERR|L_CONS, "%s[%d] Failed to link to module '%s':"
				" %s\n", cffilename, cflineno, module_name, lt_dlerror());
		return NULL;
	}

	/* make room for the module type */
	node = (module_list_t *) rad_malloc(sizeof(module_list_t));

	/* fill in the module structure */
	node->next = NULL;
	node->handle = handle;
	strNcpy(node->name, module_name, sizeof(node->name));
	
	/*
	 *	Link to the module's rlm_FOO{} module structure.
	 */
	/* module_name has the version embedded; strip it. */
	strcpy(module_struct, module_name);
	p = strrchr(module_struct, '-');
	if (p)
		*p = '\0';
	node->module = (module_t *) lt_dlsym(node->handle, module_struct);
	if (!node->module) {
		radlog(L_ERR|L_CONS, "%s[%d] Failed linking to "
				"%s structure in %s: %s\n",
				cffilename, cflineno,
				module_name, cffilename, lt_dlerror());
		lt_dlclose(node->handle);	/* ignore any errors */
		free(node);
		return NULL;
	}
	
	/* call the modules initialization */
	if (node->module->init && (node->module->init)() < 0) {
		radlog(L_ERR|L_CONS, "%s[%d] Module initialization failed.\n",
				cffilename, cflineno);
		lt_dlclose(node->handle);	/* ignore any errors */
		free(node);
		return NULL;
	}

	DEBUG("Module: Loaded %s ", node->module->name);

	node->next = module_list;
	module_list = node;

	return node;
}
示例#20
0
/*
 *	Initialize a radclient data structure
 */
static radclient_t *radclient_init(char * auth_statement)
{
    VALUE_PAIR *vp;
    radclient_t *start, *radclient, *prev = NULL;
    int filedone = 0;
    int packet_number = 1;

    start = NULL;
    /*
     *	Determine where to read the VP's from.
     */

    /*
     *	Loop until the file is done.
     */
    /*
     *	Allocate it.
     */
    radclient = malloc(sizeof(*radclient));
    memset(radclient, 0, sizeof(*radclient));

    radclient->request = rad_alloc(1);

    radclient->request->id = -1; /* allocate when sending */
    radclient->packet_number = packet_number++;

    /*
     *	Read the VP's.
     */
    radclient->request->vps = readvp2(auth_statement, &filedone, "radclient: X");
    if (!radclient->request->vps)
    {
        radclient_free(radclient);
        return radclient; /* done: return the list */
    }

    /*
     *	Keep a copy of the the User-Password attribute.
     */
    if ((vp = pairfind(radclient->request->vps, PW_PASSWORD)) != NULL)
    {
        strNcpy(radclient->password, (char *)vp->strvalue, sizeof(radclient->password));
        /*
         *	Otherwise keep a copy of the CHAP-Password attribute.
         */
    }
    else if ((vp = pairfind(radclient->request->vps, PW_CHAP_PASSWORD)) != NULL)
    {
        strNcpy(radclient->password, (char *)vp->strvalue, sizeof(radclient->password));
    }
    else
    {
        radclient->password[0] = '\0';
    }

    /*
     *  Fix up Digest-Attributes issues
     */
    for (vp = radclient->request->vps; vp != NULL; vp = vp->next)
    {
        switch (vp->attribute)
        {
        default:
            break;

            /*
             *	Allow it to set the packet type in
             *	the attributes read from the file.
             */
        case PW_PACKET_TYPE:
            radclient->request->code = vp->lvalue;
            break;

        case PW_PACKET_DST_PORT:
            radclient->request->dst_port = (vp->lvalue & 0xffff);
            break;

        case PW_DIGEST_REALM:
        case PW_DIGEST_NONCE:
        case PW_DIGEST_METHOD:
        case PW_DIGEST_URI:
        case PW_DIGEST_QOP:
        case PW_DIGEST_ALGORITHM:
        case PW_DIGEST_BODY_DIGEST:
        case PW_DIGEST_CNONCE:
        case PW_DIGEST_NONCE_COUNT:
        case PW_DIGEST_USER_NAME:
            /* overlapping! */
            memmove(&vp->strvalue[2], &vp->strvalue[0], vp->length);
            vp->strvalue[0] = vp->attribute - PW_DIGEST_REALM + 1;
            vp->length += 2;
            vp->strvalue[1] = vp->length;
            vp->attribute = PW_DIGEST_ATTRIBUTES;
            break;
        }
    } /* loop over the VP's we read in */

    if (!start)
    {
        start = radclient;
        prev = start;
    }
    else
    {
        prev->next = radclient;
        radclient->prev = prev;
        prev = radclient;
    }

    /*
     *	And we're done.
     */
    return radclient;
}
示例#21
0
/*
 *	Compare two RADIUS_PACKET data structures, based on a number
 *	of criteria.
 */
static int send_one_packet(radclient_t *radclient)
{
    int i;

    assert(radclient->done == 0);

    /*
     *	Remember when we have to wake up, to re-send the
     *	request, of we didn't receive a response.
     */
    if ((sleep_time == -1) ||
            (sleep_time > (int) timeout))
    {
        sleep_time = (int) timeout;
    }

    /*
     *	Haven't sent the packet yet.  Initialize it.
     */
    if (radclient->request->id == -1)
    {
        int found = 0;

        assert(radclient->reply == NULL);

        /*
         *	Find a free packet Id
         */
        for (i = 0; i < 256; i++)
        {
            if (radius_id[(last_used_id + i) & 0xff] == 0)
            {
                last_used_id = (last_used_id + i) & 0xff;
                radius_id[last_used_id] = 1;
                radclient->request->id = last_used_id++;
                found = 1;
                break;
            }
        }

        /*
         *	Didn't find a free packet ID, we're not done,
         *	we don't sleep, and we stop trying to process
         *	this packet.
         */
        if (!found)
        {
            done = 0;
            sleep_time = 0;
            return 0;
        }

        assert(radclient->request->id != -1);
        assert(radclient->request->data == NULL);

        librad_md5_calc(radclient->request->vector, radclient->request->vector,
                        sizeof(radclient->request->vector));

        /*
         *	Update the password, so it can be encrypted with the
         *	new authentication vector.
         */
        if (radclient->password[0] != '\0')
        {
            VALUE_PAIR *vp;

            if ((vp = pairfind(radclient->request->vps, PW_PASSWORD)) != NULL)
            {
                strNcpy((char *)vp->strvalue, radclient->password, sizeof(vp->strvalue));
                vp->length = strlen(vp->strvalue);

            }
            else if ((vp = pairfind(radclient->request->vps, PW_CHAP_PASSWORD)) != NULL)
            {
                strNcpy((char *)vp->strvalue, radclient->password, sizeof(vp->strvalue));
                vp->length = strlen(vp->strvalue);

                rad_chap_encode(radclient->request, (char *) vp->strvalue, radclient->request->id, vp);
                vp->length = 17;
            }
        }

        radclient->timestamp = time(NULL);
        radclient->tries = 1;
        radclient->resend++;

        /*
         *	Duplicate found.  Serious error!
         */
    }
    else  		/* radclient->request->id >= 0 */
    {
        time_t now = time(NULL);

        /*
         *	FIXME: Accounting packets are never retried!
         *	The Acct-Delay-Time attribute is updated to
         *	reflect the delay, and the packet is re-sent
         *	from scratch!
         */

        /*
         *	Not time for a retry, do so.
         */
        if ((now - radclient->timestamp) < timeout)
        {
            /*
             *	When we walk over the tree sending
             *	packets, we update the minimum time
             *	required to sleep.
             */
            if ((sleep_time == -1) ||
                    (sleep_time > (now - radclient->timestamp)))
            {
                sleep_time = now - radclient->timestamp;
            }
            return 0;
        }

        /*
         *	We're not trying later, maybe the packet is done.
         */
        if (radclient->tries == retries)
        {
            assert(radclient->request->id >= 0);

            /*
             *	Delete the request from the tree of
             *	outstanding requests.
             */

            fprintf(stderr, "radclient: no response from server for ID %d\n", radclient->request->id);
            /*
             *	Normally we mark it "done" when we've received
             *	the response, but this is a special case.
             */
            if (radclient->resend == resend_count)
            {
                radclient->done = 1;
            }
            totallost++;
            return -1;
        }

        /*
         *	We are trying later.
         */
        radclient->timestamp = now;
        radclient->tries++;
    }


    /*
     *	Send the packet.
     */
    if (rad_send(radclient->request, NULL, secret) < 0)
    {
        fprintf(stderr, "radclient: Failed to send packet for ID %d: %s\n",
                radclient->request->id, librad_errstr);
    }

    return 0;
}
示例#22
0
static int do_packet(int allports, uint32_t nasaddr, const struct radutmp *u)
{
	int i, retries=5, timeout=3;
	struct timeval tv;
	RADIUS_PACKET *req, *rep = NULL;
	VALUE_PAIR *vp;
	const char *secret;

	if ((req = rad_alloc(1)) == NULL) {
		librad_perror("radzap");
		exit(1);
	}
	req->id = getpid() & 0xFF;
	req->code = PW_ACCOUNTING_REQUEST;
	req->dst_port = acct_port;
	if(req->dst_port == 0) 
		req->dst_port = getport("radacct");
	if(req->dst_port == 0) 
		req->dst_port = PW_ACCT_UDP_PORT;
	if (radiusip == INADDR_NONE) {
		req->dst_ipaddr = ip_getaddr("localhost");
	}
	else {
		req->dst_ipaddr = radiusip;
	}
	if(!req->dst_ipaddr) 
		req->dst_ipaddr = 0x7f000001;
	req->vps = NULL;
	secret = getsecret(req->dst_ipaddr);

	if(allports != 0) {
		INTPAIR(PW_ACCT_STATUS_TYPE, PW_STATUS_ACCOUNTING_OFF);
		IPPAIR(PW_NAS_IP_ADDRESS, nasaddr);
		INTPAIR(PW_ACCT_DELAY_TIME, 0);
	} else {
		char login[sizeof u->login+1];
		char session_id[sizeof u->session_id+1];
		strNcpy(login, u->login, sizeof login);
		strNcpy(session_id, u->session_id, sizeof session_id);
		INTPAIR(PW_ACCT_STATUS_TYPE, PW_STATUS_STOP);
		IPPAIR(PW_NAS_IP_ADDRESS, u->nas_address);
		INTPAIR(PW_ACCT_DELAY_TIME, 0);
		STRINGPAIR(PW_USER_NAME, login);
		INTPAIR(PW_NAS_PORT, u->nas_port);
		STRINGPAIR(PW_ACCT_SESSION_ID, session_id);
		if(u->proto=='P') {
			INTPAIR(PW_SERVICE_TYPE, PW_FRAMED_USER);
			INTPAIR(PW_FRAMED_PROTOCOL, PW_PPP);
		} else if(u->proto=='S') {
			INTPAIR(PW_SERVICE_TYPE, PW_FRAMED_USER);
			INTPAIR(PW_FRAMED_PROTOCOL, PW_SLIP);
		} else {
			INTPAIR(PW_SERVICE_TYPE, PW_LOGIN_USER); /* A guess, really */
		}
		IPPAIR(PW_FRAMED_IP_ADDRESS, u->framed_address);
		INTPAIR(PW_ACCT_SESSION_TIME, 0);
		INTPAIR(PW_ACCT_INPUT_OCTETS, 0);
		INTPAIR(PW_ACCT_OUTPUT_OCTETS, 0);
		INTPAIR(PW_ACCT_INPUT_PACKETS, 0);
		INTPAIR(PW_ACCT_OUTPUT_PACKETS, 0);
	}
	if ((req->sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
		perror("radzap: socket: ");
		exit(1);
	}

	for (i = 0; i < retries; i++) {
		fd_set rdfdesc;

		rad_send(req, NULL, secret);

		/* And wait for reply, timing out as necessary */
		FD_ZERO(&rdfdesc);
		FD_SET(req->sockfd, &rdfdesc);

		tv.tv_sec = (int)timeout;
		tv.tv_usec = 1000000 * (timeout - (int)timeout);

		/* Something's wrong if we don't get exactly one fd. */
		if (select(req->sockfd + 1, &rdfdesc, NULL, NULL, &tv) != 1) {
			continue;
		}

		rep = rad_recv(req->sockfd);
		if (rep != NULL) {
			break;
		} else {	/* NULL: couldn't receive the packet */
			librad_perror("radzap:");
			exit(1);
		}
	}

	/* No response or no data read (?) */
	if (i == retries) {
		fprintf(stderr, "%s: no response from server\n", progname);
		exit(1);
	}

	if (rad_decode(rep, req, secret) != 0) {
		librad_perror("rad_decode");
		exit(1);
	}

	vp_printlist(stdout, rep->vps);
	return 0;
}