s6 = (struct sockaddr_in6 *)&dst;
sizeof_dst = sizeof(struct sockaddr_in6);
-
+
s6->sin6_family = AF_INET6;
s6->sin6_addr = dst_ipaddr->ipaddr.ip6addr;
s6->sin6_port = htons(dst_port);
if ((dst_ipaddr->af == AF_INET) ||
(src_ipaddr->af != AF_UNSPEC)) {
return sendfromto(sockfd, data, data_len, flags,
- (struct sockaddr *)&src, sizeof_src,
+ (struct sockaddr *)&src, sizeof_src,
(struct sockaddr *)&dst, sizeof_dst);
}
#else
/*
* No udpfromto, OR an IPv6 socket, fail gracefully.
*/
- return sendto(sockfd, data, data_len, flags,
+ return sendto(sockfd, data, data_len, flags,
(struct sockaddr *)&dst, sizeof_dst);
}
* Anything after 4k will be discarded.
*/
} else if (packet_len > MAX_PACKET_LEN) {
- recvfrom(sockfd, header, sizeof(header), 0,
+ recvfrom(sockfd, header, sizeof(header), 0,
(struct sockaddr *)&src, &sizeof_src);
return 1;
}
#endif
} else {
- recvfrom(sockfd, header, sizeof(header), 0,
+ recvfrom(sockfd, header, sizeof(header), 0,
(struct sockaddr *)&src, &sizeof_src);
return 1;
}
* Too little data is available, discard the packet.
*/
if (data_len < 4) {
- recvfrom(sockfd, header, sizeof(header), flags,
+ recvfrom(sockfd, header, sizeof(header), flags,
(struct sockaddr *)&src, &sizeof_src);
return 0;
* a RADIUS header length: discard it.
*/
if (len < AUTH_HDR_LEN) {
- recvfrom(sockfd, header, sizeof(header), flags,
+ recvfrom(sockfd, header, sizeof(header), flags,
(struct sockaddr *)&src, &sizeof_src);
return 0;
* Anything after 4k will be discarded.
*/
} else if (len > MAX_PACKET_LEN) {
- recvfrom(sockfd, header, sizeof(header), flags,
+ recvfrom(sockfd, header, sizeof(header), flags,
(struct sockaddr *)&src, &sizeof_src);
return len;
}
#ifdef WITH_UDPFROMTO
if (dst.ss_family == AF_INET) {
data_len = recvfromto(sockfd, buf, len, flags,
- (struct sockaddr *)&src, &sizeof_src,
+ (struct sockaddr *)&src, &sizeof_src,
(struct sockaddr *)&dst, &sizeof_dst);
} else
#endif
/*
* No udpfromto, OR an IPv6 socket. Fail gracefully.
*/
- data_len = recvfrom(sockfd, buf, len, flags,
+ data_len = recvfrom(sockfd, buf, len, flags,
(struct sockaddr *)&src, &sizeof_src);
if (data_len < 0) {
free(buf);
free(buf);
return -1; /* Unknown address family, Die Die Die! */
}
-
+
/*
* Different address families should never happen.
*/
if (TAG_VALID(vp->flags.tag)) {
ptr[0] = vp->flags.tag & 0xff;
offset = 1;
-
+
} else if (vp->flags.encrypt == FLAG_ENCRYPT_TUNNEL_PASSWORD) {
/*
* Tunnel passwords REQUIRE a tag, even
offset = 1;
} /* else don't write a tag */
} /* else the attribute doesn't have a tag */
-
+
/*
* Set up the default sources for the data.
*/
case PW_TYPE_ABINARY:
/* nothing more to do */
break;
-
+
case PW_TYPE_BYTE:
len = 1; /* just in case */
array[0] = vp->vp_integer & 0xff;
data = array;
offset = 0;
break;
-
+
case PW_TYPE_SHORT:
len = 2; /* just in case */
data = &array[offset];
len -= offset;
break;
-
+
case PW_TYPE_IPADDR:
data = (const uint8_t *) &vp->vp_ipaddr;
len = 4; /* just in case */
*/
if (len + offset + total_length > 255) {
len = 255 - offset - total_length;
- }
+ }
/*
* Encrypt the various password styles
data, len,
secret, packet->vector);
break;
-
+
case FLAG_ENCRYPT_TUNNEL_PASSWORD:
if (!original) {
librad_log("ERROR: No request packet, cannot encrypt %s attribute in the vp.", vp->name);
len = AUTH_VECTOR_LEN;
break;
-
+
default:
/*
* Just copy the data over
VALUE_PAIR *reply;
const char *what;
char ip_buffer[128];
-
+
/*
* For simplicity in the following logic, we allow
* the attributes to "overflow" the 4k maximum
return -1;
}
break;
-
+
/*
* These packet vectors start off as all zero.
*/
case PW_COA_REQUEST:
memset(packet->vector, 0, sizeof(packet->vector));
break;
-
+
default:
break;
}
-
+
/*
* Use memory on the stack, until we know how
* large the packet will be.
*/
hdr = (radius_packet_t *) data;
-
+
/*
* Build standard header
*/
hdr->code = packet->code;
hdr->id = packet->id;
-
+
memcpy(hdr->vector, packet->vector, sizeof(hdr->vector));
total_length = AUTH_HDR_LEN;
-
+
/*
* Load up the configuration values for the user
*/
* Hmm... this may be slower than just doing a small
* memcpy.
*/
-
+
/*
* Loop over the reply attributes for the packet.
*/
((reply->attribute & 0xFFFF) > 0xff)) {
continue;
}
-
+
/*
* Set the Message-Authenticator to the correct
* length and initial value.
* them out BEFORE they're encrypted.
*/
debug_pair(reply);
-
+
len = rad_vp2attr(packet, original, secret, reply, ptr);
if (len < 0) return -1;
ptr += len;
total_length += len;
} /* done looping over all attributes */
-
+
/*
* Fill in the rest of the fields, and copy the data over
* from the local stack to the newly allocated memory.
memcpy(packet->data, data, packet->data_len);
hdr = (radius_packet_t *) packet->data;
-
+
total_length = htons(total_length);
memcpy(hdr->length, &total_length, sizeof(total_length));
*/
if (packet->offset > 0) {
uint8_t calc_auth_vector[AUTH_VECTOR_LEN];
-
+
switch (packet->code) {
case PW_ACCOUNTING_REQUEST:
case PW_ACCOUNTING_RESPONSE:
default: /* others have vector already set to zero */
break;
-
+
}
-
+
/*
* Set the authentication vector to zero,
* calculate the signature, and put it
calc_auth_vector);
memcpy(packet->data + packet->offset + 2,
calc_auth_vector, AUTH_VECTOR_LEN);
-
+
/*
* Copy the original request vector back
* to the raw packet.
*/
memcpy(hdr->vector, packet->vector, AUTH_VECTOR_LEN);
}
-
+
/*
* Switch over the packet code, deciding how to
* sign the packet.
case PW_AUTHENTICATION_REQUEST:
case PW_STATUS_SERVER:
break;
-
+
/*
* Reply packets are signed with the
* authentication vector of the request.
default:
{
uint8_t digest[16];
-
+
MD5_CTX context;
MD5Init(&context);
MD5Update(&context, packet->data, packet->data_len);
MD5Update(&context, secret, strlen(secret));
MD5Final(digest, &context);
-
+
memcpy(hdr->vector, digest, AUTH_VECTOR_LEN);
memcpy(packet->vector, digest, AUTH_VECTOR_LEN);
break;
if (rad_encode(packet, original, secret) < 0) {
return -1;
}
-
+
/*
* Re-sign it, including updating the
* Message-Authenticator.
attr[1] - 2);
return 0;
}
- seen_ma = 1;
+ seen_ma = 1;
break;
}
if ((vp = paircreate(attribute, PW_TYPE_OCTETS)) == NULL) {
return NULL;
}
-
+
/*
* If length is greater than 253, something is SERIOUSLY
* wrong.
vp->length = strlen(vp->vp_strvalue);
}
break;
-
+
/*
* Tunnel-Password's may go ONLY
* in response packets.
*/
case FLAG_ENCRYPT_TUNNEL_PASSWORD:
if (!original) goto raw;
-
+
if (rad_tunnel_pwdecode(vp->vp_octets, &vp->length,
secret, original->vector) < 0) {
goto raw;
}
break;
-
+
/*
* Ascend-Send-Secret
* Ascend-Receive-Secret
if (vp->length != 8) goto raw;
/* vp->vp_ifid == vp->vp_octets */
break;
-
+
/*
* IPv6 addresses are 16 octets long
*/
if (vp->length != 16) goto raw;
/* vp->vp_ipv6addr == vp->vp_octets */
break;
-
+
/*
* IPv6 prefixes are 2 to 18 octets long.
*
vp->type = PW_TYPE_OCTETS;
vp->length = length;
memcpy(vp->vp_octets, data, length);
-
+
/*
* Ensure there's no encryption or tag stuff,
packet_length -= 2;
if (attribute != PW_VENDOR_SPECIFIC) goto create_pair;
-
+
/*
* No vendor code, or ONLY vendor code.
*/
vendorlen = 0;
}
-
+
/*
* Handle Vendor-Specific
*/
uint8_t *subptr;
int sublen;
int myvendor;
-
+
/*
* attrlen was checked above.
*/
* Zero isn't allowed.
*/
if (myvendor == 0) goto create_pair;
-
+
/*
* This is an implementation issue.
* We currently pack vendor into the upper
* than 16 bits.
*/
if (myvendor > 65535) goto create_pair;
-
+
vsa_tlen = vsa_llen = 1;
dv = dict_vendorbyvalue(myvendor);
if (dv) {
vsa_tlen = dv->type;
vsa_llen = dv->length;
}
-
+
/*
* Sweep through the list of VSA's,
* seeing if they exactly fill the
* Don't have a type, it's bad.
*/
if (sublen < vsa_tlen) goto create_pair;
-
+
/*
* Ensure that the attribute number
* is OK.
case 1:
myattr = subptr[0];
break;
-
+
case 2:
myattr = (subptr[0] << 8) | subptr[1];
break;
-
+
case 4:
if ((subptr[0] != 0) ||
(subptr[1] != 0)) goto create_pair;
-
+
myattr = (subptr[2] << 8) | subptr[3];
break;
-
+
/*
* Our dictionary is broken.
*/
default:
goto create_pair;
}
-
+
/*
* Not enough room for one more
* attribute. Die!
case 1:
attribute = ptr[0];
break;
-
+
case 2:
attribute = (ptr[0] << 8) | ptr[1];
break;
case 1:
attrlen = ptr[0] - (vsa_tlen + vsa_llen);
break;
-
+
case 2:
attrlen = ptr[1] - (vsa_tlen + vsa_llen);
break;
* random pool.
*/
lrad_rand_seed(packet->data, AUTH_HDR_LEN);
-
+
return 0;
}
* Use the secret to setup the decryption digest
*/
secretlen = strlen(secret);
-
+
lrad_MD5Init(&context);
lrad_MD5Update(&context, secret, secretlen);
old = context; /* save intermediate work */
AUTH_PASS_LEN);
lrad_MD5Final(digest, &context);
}
-
+
for (i = 0; i < AUTH_PASS_LEN; i++) {
passwd[i + n] ^= digest[i];
}
* Use the secret to setup the decryption digest
*/
secretlen = strlen(secret);
-
+
lrad_MD5Init(&context);
lrad_MD5Update(&context, secret, secretlen);
old = context; /* save intermediate work */
context = old;
if (pwlen > (n + AUTH_PASS_LEN)) lrad_MD5Update(&context, passwd + n, AUTH_PASS_LEN);
}
-
+
for (i = 0; i < AUTH_PASS_LEN; i++) {
passwd[i + n] ^= digest[i];
}
*/
if (!lrad_rand_initialized) {
int fd;
-
+
memset(&lrad_rand_pool, 0, sizeof(lrad_rand_pool));
fd = open("/dev/urandom", O_RDONLY);
hash = lrad_rand();
if (!hash) hash = lrad_rand();
hash = lrad_hash_update(data, size, hash);
-
+
lrad_rand_pool.randmem[lrad_rand_pool.randcnt] ^= hash;
}