Whitespace changes only, from a fresh checkout.
For bug # 13
void cf_section_free(CONF_SECTION **cp);
int cf_section_parse(CONF_SECTION *cs, void *base, const CONF_PARSER *variables);
-CONF_SECTION *conf_read(const char *fromfile, int fromline,
+CONF_SECTION *conf_read(const char *fromfile, int fromline,
const char *conffile, CONF_SECTION *parent);
-
+
CONF_PAIR *cf_pair_find(CONF_SECTION *section, const char *name);
CONF_PAIR *cf_pair_find_next(CONF_SECTION *section, CONF_PAIR *pair, const char *name);
CONF_SECTION *cf_section_find(const char *name);
/* modcall.h: the outside interface to the module-calling tree. Includes
* functions to build the tree from the config file, and to call it by
* feeding it REQUESTs.
- *
+ *
* Version: $Id$ */
#include "conffile.h" /* Need CONF_* definitions */
/*
* Per-instance data structure, to correlate the modules
- * with the instance names (may NOT be the module names!),
+ * with the instance names (may NOT be the module names!),
* and the per-instance data structures.
*/
typedef struct module_instance_t {
#define PW_NAS_PROMPT_USER 7
#define PW_AUTHENTICATE_ONLY 8
#define PW_CALLBACK_NAS_PROMPT 9
-
+
/* Framed Protocols */
#define PW_PPP 1
#else
-#define RAD_SNMP_INC(_x)
+#define RAD_SNMP_INC(_x)
#define RAD_SNMP_FD_INC(_fd, _x)
#endif /* WITH_SNMP */
* You should have received a copy of the GNU General Public License
* along with GNU Zebra; see the file COPYING. If not, write to the Free
* Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
+ * 02111-1307, USA.
*/
#ifndef _SMUX_H
void smux_start(void);
void smux_stop(void);
void smux_register_mib(const char *, struct variable *, size_t, int, oid [], size_t);
-int smux_header_generic (struct variable *, oid [], size_t *, int, size_t *,
+int smux_header_generic (struct variable *, oid [], size_t *, int, size_t *,
WriteMethod **);
int smux_open(void);
int smux_str2oid (char *str, oid *my_oid, size_t *oid_len);
T_RBRACE, /* ) */
T_COMMA, /* , */
T_SEMICOLON, /* ; */
-
+
T_OP_ADD, /* += */
T_OP_SUB, /* -= */
T_OP_SET, /* := */
{
char *passwd;
int cmp = 0;
-
+
#ifdef HAVE_PTHREAD_H
/*
* Ensure we're thread-safe, as crypt() isn't.
pthread_mutex_init(&lrad_crypt_mutex, NULL);
lrad_crypt_init = 1;
}
-
+
pthread_mutex_lock(&lrad_crypt_mutex);
#endif
-
+
passwd = crypt(key, crypted);
/*
if (passwd) {
cmp = strcmp(crypted, passwd);
}
-
+
#ifdef HAVE_PTHREAD_H
pthread_mutex_unlock(&lrad_crypt_mutex);
#endif
-
+
/*
* Error.
*/
rbtree_insert(values_fixup, dval);
return 0;
}
-
+
/*
* Add the value into the dictionary.
*/
flags.has_tag = 1;
}
else if (strncmp(s, "len+=", 5) == 0 ||
- strncmp(s, "len-=", 5) == 0) {
+ strncmp(s, "len-=", 5) == 0) {
/* Length difference, to accomodate
braindead NASes & their vendors */
flags.len_disp = strtol(s + 5, &c, 0);
/* Encryption method, defaults to 0 (none).
Currently valid is just type 2,
Tunnel-Password style, which can only
- be applied to strings. */
+ be applied to strings. */
flags.encrypt = strtol(s + 8, &c, 0);
if (*c) {
librad_log( "dict_init: %s[%d] invalid option %s",
/* Must be a vendor 'flag'... */
if (strncmp(s, "vendor=", 5) == 0) {
/* New format */
- s += 5;
+ s += 5;
}
-
+
vendor = dict_vendorbyname(s);
if (!vendor) {
librad_log( "dict_init: %s[%d]: unknown vendor %s",
sscanf(valstr, "%i", &value);
if (dict_addvalue(namestr, attrstr, value) < 0) {
- librad_log("dict_init: %s[%d]: %s",
+ librad_log("dict_init: %s[%d]: %s",
fn, line, librad_errstr);
return -1;
}
*/
static int attrvalue_cmp(const void *a, const void *b)
{
- return (((const DICT_ATTR *)a)->attr -
+ return (((const DICT_ATTR *)a)->attr -
((const DICT_ATTR *)b)->attr);
}
static int valuename_cmp(const void *a, const void *b)
{
int rcode;
- rcode = (((const DICT_VALUE *)a)->attr -
+ rcode = (((const DICT_VALUE *)a)->attr -
((const DICT_VALUE *)b)->attr);
if (rcode != 0) return rcode;
static int valuevalue_cmp(const void *a, const void *b)
{
int rcode;
- rcode = (((const DICT_VALUE *)a)->attr -
+ rcode = (((const DICT_VALUE *)a)->attr -
((const DICT_VALUE *)b)->attr);
if (rcode != 0) return rcode;
- return (((const DICT_VALUE *)a)->value -
+ return (((const DICT_VALUE *)a)->value -
((const DICT_VALUE *)b)->value);
}
(const char *) ((const DICT_VALUE *)b)->attr);
if (rcode != 0) return rcode;
- return (((const DICT_VALUE *)a)->value -
+ return (((const DICT_VALUE *)a)->value -
((const DICT_VALUE *)b)->value);
}
} else {
DICT_ATTR myattr;
-
+
myattr.attr = val;
- return rbtree_finddata(attributes_byvalue, &myattr);
+ return rbtree_finddata(attributes_byvalue, &myattr);
}
return NULL; /* never reached, but useful */
DICT_ATTR *dict_attrbyname(const char *name)
{
DICT_ATTR myattr;
-
+
strNcpy(myattr.name, name, sizeof(myattr.name));
-
- return rbtree_finddata(attributes_byname, &myattr);
+
+ return rbtree_finddata(attributes_byname, &myattr);
}
/*
*
* value: A value to compare against the masked bits at
* offset in a users packet.
- *
+ *
* compNeq: Defines type of comarison (Equal or Notequal)
* default is Equal.
*
argv[argc] = str;
argc++;
-
+
while (*str && (*str != ' ')) str++;
}
*
* cmd: One of ">" or "<" or "=" or "!=".
*
- * value: Socket value to be compared against, in hex.
- *
+ * value: Socket value to be compared against, in hex.
+ *
* dstipxnet: Keyword for destination IPX address.
- * nnnn = IPX Node address.
- *
+ * nnnn = IPX Node address.
+ *
* dstipxnode: Keyword for destination IPX Node address.
* mmmmm = IPX Node Address, could be FFFFFF.
* A valid ipx node number should accompany ipx net number.
- *
+ *
* dstipxsoc: Keyword for destination IPX socket address.
- *
+ *
* cmd: One of ">" or "<" or "=" or "!=".
- *
+ *
* value: Socket value to be compared against, in hex.
*/
static int ascend_parse_ipx(int argc, char **argv, ascend_ipx_filter_t *filter)
argv += rcode + 1;
flags |= 0x01;
break;
-
+
case FILTER_IPX_DST_IPXNET:
if (flags & 0x02) return -1;
rcode = ascend_parse_ipx_net(argc - 1, argv + 1,
argv += rcode + 1;
flags |= 0x02;
break;
-
+
default:
librad_log("Unknown string \"%s\" in IPX data filter",
argv[0]);
* Do the last one, too.
*/
if (ip[count] > 255) return -1;
-
+
/*
* 24, 16, 8, 0, done.
*/
* reply. The format of the string is:
*
* ip dir action [ dstip n.n.n.n/nn ] [ srcip n.n.n.n/nn ]
- * [ proto [ dstport cmp value ] [ srcport cmd value ] [ est ] ]
+ * [ proto [ dstport cmp value ] [ srcport cmd value ] [ est ] ]
*
* Fields in [...] are optional.
*
* dstip: Keyword for destination IP address.
- * n.n.n.n = IP address. /nn - netmask.
- *
+ * n.n.n.n = IP address. /nn - netmask.
+ *
* srcip: Keyword for source IP address.
- * n.n.n.n = IP address. /nn - netmask.
- *
+ * n.n.n.n = IP address. /nn - netmask.
+ *
* proto: Optional protocol field. Either a name or
* number. Known names are in FilterProtoName[].
- *
+ *
* dstport: Keyword for destination port. Only valid with tcp
* or udp. 'cmp' are in FilterPortType[]. 'value' can be
* a name or number.
* srcport: Keyword for source port. Only valid with tcp
* or udp. 'cmp' are in FilterPortType[]. 'value' can be
* a name or number.
- *
+ *
* est: Keyword for TCP established. Valid only for tcp.
- *
+ *
*/
static int ascend_parse_ip(int argc, char **argv, ascend_ip_filter_t *filter)
{
argv += 2;
argc -= 2;
break;
-
+
/*
* Should be protocol, ASCII or otherwise.
*/
argc--;
flags = 0x07;
break;
-
+
/*
* Unknown thingy.
*/
*
* Fields in [...] are optional.
*
- * offset: A Number. Specifies an offset into a frame
+ * offset: A Number. Specifies an offset into a frame
* to start comparing.
- *
+ *
* mask: A hexadecimal mask of bits to compare.
- *
+ *
* value: A value to compare with the masked data.
*
* compNeq: Defines type of comparison. ( "==" or "!=")
* Default is "==".
- *
+ *
* more: Optional keyword MORE, to represent the attachment
* to the next entry.
*/
filter->compNeq = FALSE;
flags |= 0x01;
break;
-
+
case FILTER_MORE:
if (flags & 0x02) return -1;
filter->more = htons( 1 );
*
* pair: Pointer to value_pair to place return.
*
- * valstr: The string to parse
+ * valstr: The string to parse
*
* return: -1 for error or 0.
*/
-int
+int
ascend_parse_filter(VALUE_PAIR *pair)
{
int token, type;
int argc;
char *argv[32];
ascend_filter_t filter;
-
+
rcode = -1;
-
+
/*
* Tokenize the input string in the VP.
*
*/
argc = str2argv(pair->strvalue, argv, 32);
if (argc < 3) return -1;
-
+
/*
* Decide which filter type it is: ip, ipx, or generic
*/
type = lrad_str2int(filterType, argv[0], -1);
memset(&filter, 0, sizeof(filter));
-
+
/*
* Validate the filter type.
*/
case RAD_FILTER_IPX:
filter.type = type;
break;
-
+
default:
librad_log("Unknown Ascend filter type \"%s\"", argv[0]);
return -1;
break;
}
-
+
/*
* Parse direction
*/
default: /* should never reach here. */
break;
}
-
+
/*
* Touch the VP only if everything was OK.
*/
pair->length = SIZEOF_RADFILTER;
memcpy(pair->strvalue, &filter, sizeof(filter));
}
-
+
return rcode;
-
+
#if 0
/*
- * if 'more' is set then this new entry must exist, be a
- * FILTER_GENERIC_TYPE, direction and disposition must match for
- * the previous 'more' to be valid. If any should fail then TURN OFF
+ * if 'more' is set then this new entry must exist, be a
+ * FILTER_GENERIC_TYPE, direction and disposition must match for
+ * the previous 'more' to be valid. If any should fail then TURN OFF
* previous 'more'
*/
if( prevRadPair ) {
filt = ( RadFilter * )prevRadPair->strvalue;
if(( tok != FILTER_GENERIC_TYPE ) || (rc == -1 ) ||
- ( prevRadPair->attribute != pair->attribute ) ||
- ( filt->indirection != radFil.indirection ) ||
+ ( prevRadPair->attribute != pair->attribute ) ||
+ ( filt->indirection != radFil.indirection ) ||
( filt->forward != radFil.forward ) ) {
gen = &filt->u.generic;
gen->more = FALSE;
if( rc != -1 && tok == FILTER_GENERIC_TYPE ) {
if( radFil.u.generic.more ) {
prevRadPair = pair;
- }
+ }
}
if( rc != -1 ) {
int i;
char *p;
ascend_filter_t filter;
-
+
static const char *action[] = {"drop", "forward"};
static const char *direction[] = {"out", "in"};
-
+
p = (char *)buffer;
/*
p += i;
len -= i;
}
-
- i = snprintf(p, len, " %s",
+
+ i = snprintf(p, len, " %s",
lrad_int2str(filterProtoName, filter.u.ip.proto, "??"));
p += i;
len -= i;
-
+
if (filter.u.ip.srcPortComp > RAD_NO_COMPARE) {
i = snprintf(p, len, " srcport %s %d",
lrad_int2str(filterCompare, filter.u.ip.srcPortComp, "??"),
p += i;
len -= i;
}
-
+
if (filter.u.ip.established) {
i = snprintf(p, len, " est");
p += i;
if (filter.u.ipx.src.net) {
i = snprintf(p, len, " srcipxnet 0x%04x srcipxnode 0x%02x%02x%02x%02x%02x%02x",
(unsigned int)ntohl(filter.u.ipx.src.net),
- filter.u.ipx.src.node[0], filter.u.ipx.src.node[1],
- filter.u.ipx.src.node[2], filter.u.ipx.src.node[3],
+ filter.u.ipx.src.node[0], filter.u.ipx.src.node[1],
+ filter.u.ipx.src.node[2], filter.u.ipx.src.node[3],
filter.u.ipx.src.node[4], filter.u.ipx.src.node[5]);
p += i;
len -= i;
if (filter.u.ipx.dst.net) {
i = snprintf(p, len, " dstipxnet 0x%04x dstipxnode 0x%02x%02x%02x%02x%02x%02x",
(unsigned int)ntohl(filter.u.ipx.dst.net),
- filter.u.ipx.dst.node[0], filter.u.ipx.dst.node[1],
- filter.u.ipx.dst.node[2], filter.u.ipx.dst.node[3],
+ filter.u.ipx.dst.node[0], filter.u.ipx.dst.node[1],
+ filter.u.ipx.dst.node[2], filter.u.ipx.dst.node[3],
filter.u.ipx.dst.node[4], filter.u.ipx.dst.node[5]);
p += i;
len -= i;
text_len = strlen(text);
lrad_hmac_md5(text, text_len, key, key_len, digest);
-
+
for (i = 0; i < 16; i++) {
printf("%02x", digest[i]);
}
printf("\n");
-
+
exit(0);
return 0;
}
j=0;
}
j++;
-
+
printf("%02x", key[i]);
}
printf("\nDATA: (%d) ",text_len);
printf("\n ");
k=0;
j=0;
- }
+ }
if(j==4) {
printf("_");
j=0;
}
k++;
j++;
-
+
printf("%02x", text[i]);
}
printf("\n");
j=0;
}
j++;
-
+
printf("%02x", digest[i]);
}
printf("\n");
key = "Jefe"
data = "what do ya want for nothing?"
data_len = 28 bytes
- digest =
+ digest =
key = 0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
printf("%02x", digest[i]);
}
printf("\n");
-
+
exit(0);
return 0;
}
m=ctx->randmem;
r=ctx->randrsl;
a=b=c=d=e=f=g=h=0x9e3779b9; /* the golden ratio */
-
+
for (i=0; i<4; ++i) { /* scramble it */
mix(a,b,c,d,e,f,g,h);
}
-
+
if (flag) {
/* initialize using the contents of r[] as the seed */
for (i=0; i<RANDSIZ; i+=8) {
m[i+4]=e; m[i+5]=f; m[i+6]=g; m[i+7]=h;
}
}
-
+
lrad_isaac(ctx); /* fill in the first set of results */
ctx->randcnt=RANDSIZ; /* prepare to use the first set of results */
}
{
uint32_t i,j;
lrad_randctx ctx;
-
+
ctx.randa = ctx.randb = ctx.randc = (uint32_t)0;
-
+
for (i=0; i<256; ++i) ctx.randrsl[i]=(uint32_t)0;
lrad_randinit(&ctx, 1);
for (i=0; i<2; ++i) {
if (hp == NULL) {
return htonl(INADDR_NONE);
}
-
+
/*
* Paranoia from a Bind vulnerability. An attacker
* can manipulate DNS entries to change the length of the
while ((n > 1) && (*src)) {
*(p++) = *(src++);
-
+
n--;
}
*p = '\0';
* Remove spaces from a string
*/
void rad_rmspace(char *str) {
- char *s = str;
+ char *s = str;
char *ptr = str;
while(ptr && *ptr!='\0') {
return result;
}
-#endif
+#endif
break;
}
strNcpy(out, a?a:"UNKNOWN-TYPE", outlen);
-
+
return strlen(out);
}
snprintf(out, outlen, "%s:%d %s ", vp->name, vp->flags.tag,
token);
-
+
len = strlen(out);
vp_prints_value(out + len, outlen - len, vp, 1);
len = strlen(out);
vp_prints_value(out + len, outlen - len, vp, 1);
- }
+ }
return strlen(out);
}
* RADIUS packet size, by one attribute.
*/
uint8_t data[MAX_PACKET_LEN + 256];
-
+
/*
* Use memory on the stack, until we know how
* large the packet will be.
default:
break;
-
+
}
memcpy(hdr->vector, packet->vector, sizeof(hdr->vector));
what, packet->id,
ip_ntoa((char *)ip_buffer, packet->dst_ipaddr),
packet->dst_port);
-
+
total_length = AUTH_HDR_LEN;
-
+
/*
* Load up the configuration values for the user
*/
if ((vendorcode == 0) &&
((vendorcode = VENDOR(reply->attribute)) != 0)) {
vendorpec = dict_vendorpec(vendorcode);
-
+
/*
* This is a potentially bad error...
* we can't find the vendor ID!
*ptr++ = 2;
total_length += 2;
}
-
+
switch(reply->type) {
-
+
/*
* Ascend binary attributes are
* stored internally in binary form.
*ptr++ = 0x00;
} /* else don't write a tag */
} /* else the attribute doesn't have a tag */
-
+
/*
* Ensure we don't go too far.
* The 'length' of the attribute
} else {
allowed -= *length_ptr;
}
-
+
if (len > allowed) {
len = allowed;
}
-
+
*length_ptr += len;
if (vsa_length_ptr) *vsa_length_ptr += len;
/*
ptr += reply->length;
total_length += len;
break;
-
+
case PW_TYPE_INTEGER:
case PW_TYPE_IPADDR:
*length_ptr += 4;
*/
if (msg_auth_offset) {
uint8_t calc_auth_vector[AUTH_VECTOR_LEN];
-
+
switch (packet->code) {
default:
break;
-
+
case PW_AUTHENTICATION_ACK:
case PW_AUTHENTICATION_REJECT:
case PW_ACCESS_CHALLENGE:
AUTH_VECTOR_LEN);
break;
}
-
+
/*
* Set the authentication vector to zero,
* calculate the signature, and put it
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;
DEBUG("Re-sending %s of id %d to %s:%d\n", what, packet->id,
ip_ntoa((char *)ip_buffer, packet->dst_ipaddr),
packet->dst_port);
-
+
for (reply = packet->vps; reply; reply = reply->next) {
/* FIXME: ignore attributes > 0xff */
debug_pair(reply);
}
}
-
+
/*
* And send it on it's way.
*/
* as the original MD5 sum (packet->vector).
*/
memset(packet->data + 4, 0, AUTH_VECTOR_LEN);
-
+
/*
* MD5(packet + secret);
*/
int seen_eap;
uint8_t data[MAX_PACKET_LEN];
int num_attributes;
-
+
/*
* Allocate the new request data structure
*/
struct sockaddr_in salocal;
salen_local = sizeof(salocal);
memset(&salocal, 0, sizeof(salocal));
- packet->data_len = recvfromto(fd, data, sizeof(data), 0,
+ packet->data_len = recvfromto(fd, data, sizeof(data), 0,
(struct sockaddr *)&saremote, &salen,
(struct sockaddr *)&salocal, &salen_local);
packet->dst_ipaddr = salocal.sin_addr.s_addr;
free(packet);
return NULL;
}
-
+
/*
* Attributes are at LEAST as long as the ID & length
* fields. Anything shorter is an invalid attribute.
}
seen_eap |= PW_MESSAGE_AUTHENTICATOR;
break;
-
+
case PW_VENDOR_SPECIFIC:
if (attr[1] <= 6) {
librad_log("WARNING: Malformed RADIUS packet from host %s: Vendor-Specific has invalid length %d",
packet_codes[hdr->code],
ip_ntoa(host_ipaddr, packet->src_ipaddr), packet->src_port);
} else {
- printf("rad_recv: Packet from host %s:%d code=%d",
+ printf("rad_recv: Packet from host %s:%d code=%d",
ip_ntoa(host_ipaddr, packet->src_ipaddr), packet->src_port,
hdr->code);
}
} else if ((vendorcode == VENDORPEC_USR) &&
((ptr[4] == 0) && (ptr[5] == 0))) {
DICT_ATTR *da;
-
+
da = dict_attrbyvalue((vendorcode << 16) |
(ptr[6] << 8) |
ptr[7]);
librad_log("out of memory");
return -1;
}
-
+
pair->length = attrlen;
pair->operator = T_OP_EQ;
pair->next = NULL;
-
+
switch (pair->type) {
-
+
/*
* The attribute may be zero length,
* or it may have a tag, and then no data...
return -1;
}
if (rad_tunnel_pwdecode(pair->strvalue,
- &pair->length,
+ &pair->length,
secret,
(char *)original->vector) < 0) {
return -1;
break;
} /* switch over encryption flags */
break; /* from octets/string/abinary */
-
+
case PW_TYPE_INTEGER:
case PW_TYPE_DATE:
case PW_TYPE_IPADDR:
}
}
break;
-
+
/*
* IPv6 interface ID is 8 octets long.
*/
pair = NULL;
break;
}
-
+
if (pair) {
debug_pair(pair);
*tail = pair;
* Length > AUTH_PASS_LEN, so we need to use the extended
* algorithm.
*/
- for (n = 0; n < 128 && n <= (len - AUTH_PASS_LEN); n += AUTH_PASS_LEN) {
+ for (n = 0; n < 128 && n <= (len - AUTH_PASS_LEN); n += AUTH_PASS_LEN) {
memcpy(buffer + secretlen, passwd + n, AUTH_PASS_LEN);
librad_md5_calc((u_char *)digest, buffer, secretlen + AUTH_PASS_LEN);
for (i = 0; i < AUTH_PASS_LEN; i++)
*/
rlen = ((pwlen - 1) / AUTH_PASS_LEN) * AUTH_PASS_LEN;
- for (n = rlen; n > 0; n -= AUTH_PASS_LEN ) {
+ for (n = rlen; n > 0; n -= AUTH_PASS_LEN ) {
s = (n == AUTH_PASS_LEN) ? r : (passwd + n - AUTH_PASS_LEN);
memcpy(buffer + secretlen, s, AUTH_PASS_LEN);
librad_md5_calc((u_char *)digest, buffer, secretlen + AUTH_PASS_LEN);
char* salt;
int i, n, secretlen;
unsigned len, n2;
-
+
len = *pwlen;
if (len > 127) len = 127;
salt[0] = (0x80 | ( ((salt_offset++) & 0x0f) << 3) |
(lrad_rand() & 0x07));
salt[1] = lrad_rand();
-
+
/*
* Padd password to multiple of AUTH_PASS_LEN bytes.
*/
}
/* set new password length */
*pwlen = len + 2;
-
+
/*
* Use the secret to setup the decryption digest
*/
secretlen = strlen(secret);
memcpy(buffer, secret, secretlen);
-
+
for (n2 = 0; n2 < len; n2+=AUTH_PASS_LEN) {
if (!n2) {
memcpy(buffer + secretlen, vector, AUTH_VECTOR_LEN);
memcpy(buffer + secretlen + AUTH_VECTOR_LEN, salt, 2);
librad_md5_calc(digest, buffer, secretlen + AUTH_VECTOR_LEN + 2);
} else {
- memcpy(buffer + secretlen, passwd + n2 - AUTH_PASS_LEN, AUTH_PASS_LEN);
+ memcpy(buffer + secretlen, passwd + n2 - AUTH_PASS_LEN, AUTH_PASS_LEN);
librad_md5_calc(digest, buffer, secretlen + AUTH_PASS_LEN);
}
-
+
for (i = 0; i < AUTH_PASS_LEN; i++) {
passwd[i + n2] ^= digest[i];
}
uint8_t decrypted[MAX_STRING_LEN + 1];
int secretlen;
unsigned i, n, len;
-
+
len = *pwlen;
/*
}
/*
- * There's a salt, but no password. Or, there's a salt
+ * There's a salt, but no password. Or, there's a salt
* and a 'data_len' octet. It's wrong, but at least we
* can figure out what it means: the password is empty.
*
i += challenge->length;
} else {
memcpy(ptr, packet->vector, AUTH_VECTOR_LEN);
- i += AUTH_VECTOR_LEN;
+ i += AUTH_VECTOR_LEN;
}
*output = id;
/**************************
* rotate Node X to left *
**************************/
-
+
rbnode_t *Y = X->Right;
-
+
/* establish X->Right link */
X->Right = Y->Left;
if (Y->Left != NIL) Y->Left->Parent = X;
-
+
/* establish Y->Parent link */
if (Y != NIL) Y->Parent = X->Parent;
if (X->Parent) {
} else {
tree->Root = Y;
}
-
+
/* link X and Y */
Y->Left = X;
if (X != NIL) X->Parent = Y;
/****************************
* rotate Node X to right *
****************************/
-
+
rbnode_t *Y = X->Left;
-
+
/* establish X->Left link */
X->Left = Y->Right;
if (Y->Right != NIL) Y->Right->Parent = X;
-
+
/* establish Y->Parent link */
if (Y != NIL) Y->Parent = X->Parent;
if (X->Parent) {
} else {
tree->Root = Y;
}
-
+
/* link X and Y */
Y->Right = X;
if (X != NIL) X->Parent = Y;
* maintain red-black tree balance *
* after inserting node X *
*************************************/
-
+
/* check red-black properties */
while (X != tree->Root && X->Parent->Color == Red) {
/* we have a violation */
if (X->Parent == X->Parent->Parent->Left) {
rbnode_t *Y = X->Parent->Parent->Right;
if (Y->Color == Red) {
-
+
/* uncle is red */
X->Parent->Color = Black;
Y->Color = Black;
X->Parent->Parent->Color = Red;
X = X->Parent->Parent;
} else {
-
+
/* uncle is black */
if (X == X->Parent->Right) {
/* make X a left child */
X = X->Parent;
RotateLeft(tree, X);
}
-
+
/* recolor and rotate */
X->Parent->Color = Black;
X->Parent->Parent->Color = Red;
RotateRight(tree, X->Parent->Parent);
}
} else {
-
+
/* mirror image of above code */
rbnode_t *Y = X->Parent->Parent->Left;
if (Y->Color == Red) {
-
+
/* uncle is red */
X->Parent->Color = Black;
Y->Color = Black;
X->Parent->Parent->Color = Red;
X = X->Parent->Parent;
} else {
-
+
/* uncle is black */
if (X == X->Parent->Left) {
X = X->Parent;
int rbtree_insert(rbtree_t *tree, void *Data)
{
rbnode_t *Current, *Parent, *X;
-
+
/***********************************************
* allocate node for Data and insert in tree *
***********************************************/
-
+
/* find where node belongs */
Current = tree->Root;
Parent = NULL;
Parent = Current;
Current = (result < 0) ? Current->Left : Current->Right;
}
-
+
/* setup new node */
if ((X = malloc (sizeof(*X))) == NULL) {
exit(1);
X->Left = NIL;
X->Right = NIL;
X->Color = Red;
-
+
/* insert node in tree */
if (Parent) {
if (tree->Compare(Data, Parent->Data) <= 0)
} else {
tree->Root = X;
}
-
+
InsertFixup(tree, X);
tree->num_elements++;
* maintain red-black tree balance *
* after deleting node X *
*************************************/
-
+
while (X != tree->Root && X->Color == Black) {
if (X == X->Parent->Left) {
rbnode_t *W = X->Parent->Right;
void rbtree_delete(rbtree_t *tree, rbnode_t *Z)
{
rbnode_t *X, *Y;
-
+
/*****************************
* delete node Z from tree *
*****************************/
-
+
if (!Z || Z == NIL) return;
-
+
if (Z->Left == NIL || Z->Right == NIL) {
/* Y has a NIL node as a child */
Y = Z;
Y = Z->Right;
while (Y->Left != NIL) Y = Y->Left;
}
-
+
/* X is Y's only child */
if (Y->Left != NIL)
X = Y->Left;
else
X = Y->Right;
-
+
/* remove Y from the parent chain */
X->Parent = Y->Parent;
if (Y->Parent)
Y->Parent->Right = X;
else
tree->Root = X;
-
+
if (Y != Z) {
/*
* Move the child's data to here, and then
/*******************************
* find node containing Data *
*******************************/
-
+
rbnode_t *Current = tree->Root;
while (Current != NIL) {
int rbtree_walk(rbtree_t *tree, int (*callback)(void *), RBTREE_ORDER order)
{
switch (order) {
- case PreOrder:
+ case PreOrder:
return WalkNodePreOrder(tree->Root, callback);
- case InOrder:
+ case InOrder:
return WalkNodeInOrder(tree->Root, callback);
- case PostOrder:
+ case PostOrder:
return WalkNodePostOrder(tree->Root, callback);
default:
*
* Version: $Id$
*/
-
+
#include "autoconf.h"
#include <string.h>
-/*
+/*
Unix SMB/CIFS implementation.
- a partial implementation of DES designed for use in the
+ a partial implementation of DES designed for use in the
SMB authentication protocol
Copyright (C) Andrew Tridgell 1998
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* NOTES:
+/* NOTES:
This code makes no attempt to be fast! In fact, it is a very
- slow implementation
+ slow implementation
This code is NOT a complete DES implementation. It implements only
the minimum necessary for SMB authentication, as used by all SMB
lshift(c, sc[i], 28);
lshift(d, sc[i], 28);
- concat(cd, c, d, 28, 28);
- permute(ki[i], cd, perm2, 48);
+ concat(cd, c, d, 28, 28);
+ permute(ki[i], cd, perm2, 48);
}
permute(pd1, in, perm3, 64);
int m, n;
m = (b[j][0]<<1) | b[j][5];
- n = (b[j][1]<<3) | (b[j][2]<<2) | (b[j][3]<<1) | b[j][4];
+ n = (b[j][1]<<3) | (b[j][2]<<2) | (b[j][3]<<1) | b[j][4];
- for (k=0;k<4;k++)
- b[j][k] = (sbox[j][m][n] & (1<<(3-k)))?1:0;
+ for (k=0;k<4;k++)
+ b[j][k] = (sbox[j][m][n] & (1<<(3-k)))?1:0;
}
for (j=0;j<8;j++)
* original. Also, there is now a builtin-test, just compile with:
* gcc -DTEST_SNPRINTF -o snprintf snprintf.c -lm
* and run snprintf for results.
- *
+ *
* Thomas Roessler <roessler@guug.de> 01/27/98 for mutt 0.89i
- * The PGP code was using unsigned hexadecimal formats.
+ * The PGP code was using unsigned hexadecimal formats.
* Unfortunately, unsigned formats simply didn't work.
*
* Michael Elkins <me@cs.hmc.edu> 03/05/98 for mutt 0.90.8
#define VA_SHIFT(v,t) ; /* no-op for ANSI */
#define VA_END va_end(ap)
-static void dopr (char *buffer, size_t maxlen, const char *format,
+static void dopr (char *buffer, size_t maxlen, const char *format,
va_list args);
static void fmtstr (char *buffer, size_t *currlen, size_t maxlen,
char *value, int flags, int min, int max);
int flags;
int cflags;
size_t currlen;
-
+
state = DP_S_DEFAULT;
currlen = flags = cflags = min = 0;
max = -1;
while (state != DP_S_DONE)
{
- if ((ch == '\0') || (currlen >= maxlen))
+ if ((ch == '\0') || (currlen >= maxlen))
state = DP_S_DONE;
- switch(state)
+ switch(state)
{
case DP_S_DEFAULT:
- if (ch == '%')
+ if (ch == '%')
state = DP_S_FLAGS;
- else
+ else
dopr_outch (buffer, &currlen, maxlen, ch);
ch = *format++;
break;
case DP_S_FLAGS:
- switch (ch)
+ switch (ch)
{
case '-':
flags |= DP_F_MINUS;
}
break;
case DP_S_MIN:
- if (isdigit((int)ch))
+ if (isdigit((int)ch))
{
min = 10*min + char_to_int (ch);
ch = *format++;
- }
- else if (ch == '*')
+ }
+ else if (ch == '*')
{
min = va_arg (args, int);
ch = *format++;
state = DP_S_DOT;
- }
- else
+ }
+ else
state = DP_S_DOT;
break;
case DP_S_DOT:
- if (ch == '.')
+ if (ch == '.')
{
state = DP_S_MAX;
ch = *format++;
- }
- else
+ }
+ else
state = DP_S_MOD;
break;
case DP_S_MAX:
- if (isdigit((int)ch))
+ if (isdigit((int)ch))
{
if (max < 0)
max = 0;
max = 10*max + char_to_int (ch);
ch = *format++;
- }
- else if (ch == '*')
+ }
+ else if (ch == '*')
{
max = va_arg (args, int);
ch = *format++;
state = DP_S_MOD;
- }
- else
+ }
+ else
state = DP_S_MOD;
break;
case DP_S_MOD:
/* Currently, we don't support Long Long, bummer */
- switch (ch)
+ switch (ch)
{
case 'h':
cflags = DP_C_SHORT;
state = DP_S_CONV;
break;
case DP_S_CONV:
- switch (ch)
+ switch (ch)
{
case 'd':
case 'i':
- if (cflags == DP_C_SHORT)
+ if (cflags == DP_C_SHORT)
value = va_arg (args, short int);
else if (cflags == DP_C_LONG)
value = va_arg (args, long int);
break;
case 's':
strvalue = va_arg (args, char *);
- if (max < 0)
+ if (max < 0)
max = maxlen; /* ie, no max */
fmtstr (buffer, &currlen, maxlen, strvalue, flags, min, max);
break;
fmtint (buffer, &currlen, maxlen, (long) strvalue, 16, min, max, flags);
break;
case 'n':
- if (cflags == DP_C_SHORT)
+ if (cflags == DP_C_SHORT)
{
short int *num;
num = va_arg (args, short int *);
*num = currlen;
- }
- else if (cflags == DP_C_LONG)
+ }
+ else if (cflags == DP_C_LONG)
{
long int *num;
num = va_arg (args, long int *);
*num = currlen;
- }
- else
+ }
+ else
{
int *num;
num = va_arg (args, int *);
break; /* some picky compilers need this */
}
}
- if (currlen < maxlen - 1)
+ if (currlen < maxlen - 1)
buffer[currlen] = '\0';
- else
+ else
buffer[maxlen - 1] = '\0';
}
{
int padlen, strln; /* amount to pad */
int cnt = 0;
-
+
if (value == 0)
{
value = "<NULL>";
for (strln = 0; value[strln]; ++strln); /* strlen */
padlen = min - strln;
- if (padlen < 0)
+ if (padlen < 0)
padlen = 0;
- if (flags & DP_F_MINUS)
+ if (flags & DP_F_MINUS)
padlen = -padlen; /* Left Justify */
- while ((padlen > 0) && (cnt < max))
+ while ((padlen > 0) && (cnt < max))
{
dopr_outch (buffer, currlen, maxlen, ' ');
--padlen;
++cnt;
}
- while (*value && (cnt < max))
+ while (*value && (cnt < max))
{
dopr_outch (buffer, currlen, maxlen, *value++);
++cnt;
}
- while ((padlen < 0) && (cnt < max))
+ while ((padlen < 0) && (cnt < max))
{
dopr_outch (buffer, currlen, maxlen, ' ');
++padlen;
int spadlen = 0; /* amount to space pad */
int zpadlen = 0; /* amount to zero pad */
int caps = 0;
-
+
if (max < 0)
max = 0;
if (flags & DP_F_SPACE)
signvalue = ' ';
}
-
+
if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */
do {
zpadlen = THEMAX(zpadlen, spadlen);
spadlen = 0;
}
- if (flags & DP_F_MINUS)
+ if (flags & DP_F_MINUS)
spadlen = -spadlen; /* Left Justifty */
#ifdef DEBUG_SNPRINTF
#endif
/* Spaces */
- while (spadlen > 0)
+ while (spadlen > 0)
{
dopr_outch (buffer, currlen, maxlen, ' ');
--spadlen;
}
/* Sign */
- if (signvalue)
+ if (signvalue)
dopr_outch (buffer, currlen, maxlen, signvalue);
/* Zeros */
- if (zpadlen > 0)
+ if (zpadlen > 0)
{
while (zpadlen > 0)
{
}
/* Digits */
- while (place > 0)
+ while (place > 0)
dopr_outch (buffer, currlen, maxlen, convert[--place]);
-
+
/* Left Justified spaces */
while (spadlen < 0) {
dopr_outch (buffer, currlen, maxlen, ' ');
result *= 10;
exp--;
}
-
+
return result;
}
int iplace = 0;
int fplace = 0;
int padlen = 0; /* amount to pad */
- int zpadlen = 0;
+ int zpadlen = 0;
int caps = 0;
long intpart;
long fracpart;
-
- /*
+
+ /*
* AIX manpage says the default is 0, but Solaris says the default
* is 6, and sprintf on AIX defaults to 6
*/
intpart = ufvalue;
- /*
- * Sorry, we only support 9 digits past the decimal because of our
+ /*
+ * Sorry, we only support 9 digits past the decimal because of our
* conversion method
*/
if (max > 9)
fconvert[fplace] = 0;
/* -1 for decimal point, another -1 if we are printing a sign */
- padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0);
+ padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0);
zpadlen = max - fplace;
if (zpadlen < 0)
zpadlen = 0;
- if (padlen < 0)
+ if (padlen < 0)
padlen = 0;
- if (flags & DP_F_MINUS)
+ if (flags & DP_F_MINUS)
padlen = -padlen; /* Left Justifty */
- if ((flags & DP_F_ZERO) && (padlen > 0))
+ if ((flags & DP_F_ZERO) && (padlen > 0))
{
- if (signvalue)
+ if (signvalue)
{
dopr_outch (buffer, currlen, maxlen, signvalue);
--padlen;
dopr_outch (buffer, currlen, maxlen, ' ');
--padlen;
}
- if (signvalue)
+ if (signvalue)
dopr_outch (buffer, currlen, maxlen, signvalue);
- while (iplace > 0)
+ while (iplace > 0)
dopr_outch (buffer, currlen, maxlen, iconvert[--iplace]);
/*
*/
dopr_outch (buffer, currlen, maxlen, '.');
- while (fplace > 0)
+ while (fplace > 0)
dopr_outch (buffer, currlen, maxlen, fconvert[--fplace]);
while (zpadlen > 0)
--zpadlen;
}
- while (padlen < 0)
+ while (padlen < 0)
{
dopr_outch (buffer, currlen, maxlen, ' ');
++padlen;
int snprintf (char *str,size_t count,const char *fmt,...)
{
VA_LOCAL_DECL;
-
+
VA_START (fmt);
VA_SHIFT (str, char *);
VA_SHIFT (count, size_t );
"%3.2f",
NULL
};
- double fp_nums[] = { -1.5, 134.21, 91340.2, 341.1234, 0203.9, 0.96, 0.996,
+ double fp_nums[] = { -1.5, 134.21, 91340.2, 341.1234, 0203.9, 0.96, 0.996,
0.9996, 1.996, 4.136, 0};
char *int_fmt[] = {
"%-1.5d",
sprintf (buf2, fp_fmt[x], fp_nums[y]);
if (strcmp (buf1, buf2))
{
- printf("snprintf doesn't match Format: %s\n\tsnprintf = %s\n\tsprintf = %s\n",
+ printf("snprintf doesn't match Format: %s\n\tsnprintf = %s\n\tsprintf = %s\n",
fp_fmt[x], buf1, buf2);
fail++;
}
sprintf (buf2, int_fmt[x], int_nums[y]);
if (strcmp (buf1, buf2))
{
- printf("snprintf doesn't match Format: %s\n\tsnprintf = %s\n\tsprintf = %s\n",
+ printf("snprintf doesn't match Format: %s\n\tsnprintf = %s\n\tsprintf = %s\n",
int_fmt[x], buf1, buf2);
fail++;
}
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
*
- * Helper functions to get/set addresses of UDP packets
+ * Helper functions to get/set addresses of UDP packets
* based on recvfromto by Miquel van Smoorenburg
*
* recvfromto Like recvfrom, but also stores the destination
* version 2 of the License, or (at your option) any later version.
*
* sendfromto added 18/08/2003, Jan Berkel <jan@sitadelle.com>
- * Works on Linux and FreeBSD (5.x)
- *
+ * Works on Linux and FreeBSD (5.x)
+ *
* Version: $Id$
*/
#ifdef HAVE_IP_RECVDSTADDR
/*
- * Set the IP_RECVDSTADDR option (BSD).
- * Note: IP_RECVDSTADDR == IP_SENDSRCADDR
+ * Set the IP_RECVDSTADDR option (BSD).
+ * Note: IP_RECVDSTADDR == IP_SENDSRCADDR
*/
err = setsockopt(s, IPPROTO_IP, IP_RECVDSTADDR, &opt, sizeof(opt));
#endif
return err;
}
-
+
int recvfromto(int s, void *buf, size_t len, int flags,
struct sockaddr *from, socklen_t *fromlen,
struct sockaddr *to, socklen_t *tolen)
l = sizeof(si);
if (getsockname(s, (struct sockaddr *)&si, &l) == 0) {
((struct sockaddr_in *)to)->sin_port = si.sin_port;
- ((struct sockaddr_in *)to)->sin_addr = si.sin_addr;
+ ((struct sockaddr_in *)to)->sin_addr = si.sin_addr;
}
if (tolen) *tolen = sizeof(struct sockaddr_in);
}
# endif
}
return err;
-#else
+#else
/* fallback: call recvfrom */
return recvfrom(s, buf, len, flags, from, fromlen);
#endif /* defined(HAVE_IP_PKTINFO) || defined(HAVE_IP_RECVDSTADDR) */
msgh.msg_controllen = sizeof(cmsgbuf);
msgh.msg_name = to;
msgh.msg_namelen = tolen;
-
+
cmsg = CMSG_FIRSTHDR(&msgh);
# ifdef HAVE_IP_PKTINFO
cmsg->cmsg_level = IPPROTO_IP;
cmsg->cmsg_type = IP_SENDSRCADDR;
cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_addr));
- memcpy((struct in_addr *)CMSG_DATA(cmsg),
+ memcpy((struct in_addr *)CMSG_DATA(cmsg),
&((struct sockaddr_in *)from)->sin_addr, sizeof(struct in_addr));
# endif
/*
* Small test program to test recvfromto/sendfromto
*
- * use a virtual IP address as first argument to test
+ * use a virtual IP address as first argument to test
*
* reply packet should originate from virtual IP and not
* from the default interface the alias is bound to
return 0;
case 0:
/* child */
- usleep(100000);
+ usleep(100000);
goto client;
}
inet_ntoa(to.sin_addr), ntohs(to.sin_port));
printf("server: replying from address packet was received on to source address\n");
-
+
if ((n = sendfromto(server_socket, buf, n, 0,
(struct sockaddr *)&to, tl,
(struct sockaddr *)&from, fl)) < 0) {
in.sin_addr.s_addr = inet_addr(destip);
printf("client: sending packet to %s:%d\n", destip, port);
- if (sendto(client_socket, TESTSTRING, TESTLEN, 0,
+ if (sendto(client_socket, TESTSTRING, TESTLEN, 0,
(struct sockaddr *)&in, sizeof(in)) < 0) {
perror("client: sendto");
_exit(0);
}
-
+
printf("client: waiting for reply from server on INADDR_ANY:%d\n", port+1);
if ((n = recvfromto(client_socket, buf, sizeof(buf), 0,
*/
if (i->attribute == PW_FALL_THROUGH ||
(i->attribute != PW_HINT && i->attribute != PW_FRAMED_ROUTE)) {
-
+
found = pairfind(*to, i->attribute);
switch (i->operator) {
(strcmp((char *)found->strvalue,
(char *)i->strvalue) == 0)){
pairdelete(to, found->attribute);
-
+
/*
* 'tailto' may have been
* deleted...
tailfrom = i;
continue;
break;
-
+
/* really HAVE_REGEX_H */
-#if 0
+#if 0
/*
* Attr-Name =~ "s/find/replace/"
*
q = strchr(str, *p);
*(q++) = '\0';
q[strlen(q) - 1] = '\0';
-
+
regcomp(®, str, 0);
if (regexec(®, found->strvalue,
1, match, 0) == 0) {
tailfrom->next = next;
else
*from = next;
-
+
/*
* If ALL of the 'to' attributes have been deleted,
* then ensure that the 'tail' is updated to point
*/
tm->tm_mon = 12;
for (i = 0; i < 3; i++) {
- if (isalpha( (int) *f[i])) {
+ if (isalpha( (int) *f[i])) {
/*
* Bubble the month to the front of the list
*/
while (*cp && vp->length < MAX_STRING_LEN) {
unsigned int tmp;
-
+
if (sscanf(cp, "%02x", &tmp) != 1) {
librad_log("Non-hex characters at %c%c", cp[0], cp[1]);
return NULL;
case PW_TYPE_IFID:
if (vp->length != 8) goto length_error;
break;
-
+
case PW_TYPE_IPV6ADDR:
if (vp->length != 16) goto length_error;
break;
-
+
#ifdef ASCEND_BINARY
case PW_TYPE_ABINARY:
if (vp->length != 32) goto length_error;
break;
-#endif
+#endif
default: /* string, octets, etc. */
break;
}
else tag = 0;
}
found_tag = 1;
- }
-
+ }
+
if (found_tag) {
vp->flags.tag = tag;
}
if (res != 0) {
char msg[128];
- regerror(res, &cre, msg, sizeof(msg));
+ regerror(res, &cre, msg, sizeof(msg));
librad_log("Illegal regular expression in attribute: %s: %s",
vp->name, msg);
pairbasicfree(vp);
case T_BACK_QUOTED_STRING:
vp = pairmake(attr, NULL, token);
if (!vp) return vp;
-
+
vp->flags.do_xlat = 1;
strNcpy(vp->strvalue, value, sizeof(vp->strvalue));
vp->length = 0;
break;
}
-
+
return vp;
}
}
break;
}
-
+
pairadd(&list, vp);
buf[0] = '\0';
}
reply != RLM_MODULE_OK &&
reply != RLM_MODULE_UPDATED)
return reply;
-
+
/*
* Do accounting, ONLY the first time through.
* This is to ensure that we log the packet
if (vp)
acct_type = vp->lvalue;
reply = module_accounting(acct_type,request);
-
+
/*
* See if we need to execute a program.
* FIXME: somehow cache this info, and only execute the
exec_program = strdup((char *)vp->strvalue);
pairdelete(&request->reply->vps, PW_EXEC_PROGRAM_WAIT);
}
-
+
/*
* If we want to exec a program, but wait for it,
* do it first before sending the reply, or
*/
pairmove(&request->reply->vps, &vp);
pairfree(&vp);
-
+
if (exec_wait) {
if (rcode != 0) {
return reply;
username = request->username;
}
- /*
+ /*
* Clean up the username
*/
if (username == NULL) {
clean_username, sizeof(clean_username));
}
- /*
+ /*
* Clean up the password
*/
if (mainconfig.log_auth_badpass || mainconfig.log_auth_goodpass) {
if (goodpass) {
radlog(L_AUTH, "%s: [%s%s%s] (%s)",
- msg,
+ msg,
clean_username,
mainconfig.log_auth_goodpass ? "/" : "",
mainconfig.log_auth_goodpass ? clean_password : "",
auth_name(buf, sizeof(buf), request, 1));
} else {
radlog(L_AUTH, "%s: [%s%s%s] (%s)",
- msg,
+ msg,
clean_username,
mainconfig.log_auth_badpass ? "/" : "",
mainconfig.log_auth_badpass ? clean_password : "",
auth_name(buf, sizeof(buf), request, 1));
}
-
+
return 0;
}
}
if (( auth_type_count > 1) && (debug_flag)) {
- radlog(L_ERR, "Warning: Found %d auth-types on request for user '%s'",
+ radlog(L_ERR, "Warning: Found %d auth-types on request for user '%s'",
auth_type_count, request->username->strvalue);
}
/*
- * This means we have a proxy reply or an accept
- * and it wasn't rejected in the above loop. So
- * that means it is accepted and we do no further
+ * This means we have a proxy reply or an accept
+ * and it wasn't rejected in the above loop. So
+ * that means it is accepted and we do no further
* authentication
*/
if ((auth_type == PW_AUTHTYPE_ACCEPT) || (request->proxy)) {
"(No Crypt-Password configured for the user)", request, 0);
return -1;
}
-
+
switch (lrad_crypt_check((char *)auth_item->strvalue,
(char *)password_pair->strvalue)) {
case -1:
switch (result) {
default:
break;
-
+
/*
* The module failed, or said to reject the user: Do so.
*/
request->password = pairfind(request->packet->vps,
PW_PASSWORD);
}
-
+
/*
* Discover which password we want to use.
*/
/*
* Maybe there's a CHAP-Password?
*/
- if ((auth_item = pairfind(request->packet->vps,
+ if ((auth_item = pairfind(request->packet->vps,
PW_CHAP_PASSWORD)) != NULL) {
password = "<CHAP-PASSWORD>";
-
+
} else {
/*
* No password we recognize.
}
}
request->password = auth_item;
-
+
/*
* Get the user's authorization information from the database
*/
return RLM_MODULE_HANDLED;
}
} while(0);
-
+
/*
* Failed to validate the user.
*
}
if (!mpp_ok){
if (check_item->lvalue > 1) {
- snprintf(umsg, sizeof(umsg),
+ snprintf(umsg, sizeof(umsg),
"\r\nYou are already logged in %d times - access denied\r\n\n",
(int)check_item->lvalue);
user_msg = umsg;
tmp = pairmake("Reply-Message", user_msg, T_OP_SET);
request->reply->vps = tmp;
- snprintf(logstr, sizeof(logstr), "Outside allowed timespan (time allowed %s)",
+ snprintf(logstr, sizeof(logstr), "Outside allowed timespan (time allowed %s)",
check_item->strvalue);
rad_authlog(logstr, request, 1);
* Add the port number to the Framed-IP-Address if
* vp->addport is set.
*/
- if (((tmp = pairfind(request->reply->vps,
+ if (((tmp = pairfind(request->reply->vps,
PW_FRAMED_IP_ADDRESS)) != NULL) &&
(tmp->flags.addport != 0)) {
VALUE_PAIR *vpPortId;
-
+
/*
* Find the NAS port ID.
*/
tmp = pairmake("Reply-Message", user_msg, T_OP_SET);
pairadd(&request->reply->vps, tmp);
- rad_authlog("Login incorrect (external check failed)",
+ rad_authlog("Login incorrect (external check failed)",
request, 0);
return RLM_MODULE_REJECT;
NULL, 0, request->packet->vps, NULL);
}
- if (exec_program)
+ if (exec_program)
free(exec_program);
result = rad_postauth(request);
*/
p = buffer;
while (*p &&
- ((*p == ' ') || (*p == '\t')))
+ ((*p == ' ') || (*p == '\t')))
p++;
/*
(int) sizeof(c->shortname) - 1);
return -1;
}
-
+
/*
* It should be OK now, let's create the buffer.
*/
* Walk the RADCLIENT list displaying the clients. This function
* is for debugging purposes.
*/
-void client_walk(void)
+void client_walk(void)
{
RADCLIENT *cl;
char host_ipaddr[16];
else
return cl->longname;
}
-
- /*
- * this isn't normally reachable, but if a loggable event happens just
- * after a client list change and a HUP, then we may not know this
+
+ /*
+ * this isn't normally reachable, but if a loggable event happens just
+ * after a client list change and a HUP, then we may not know this
* information any more.
*
* If you see lots of these, then there's something wrong.
{
CONF_SECTION *cs;
- if (name1 == NULL || !name1[0])
+ if (name1 == NULL || !name1[0])
name1 = "main";
cs = (CONF_SECTION *)rad_malloc(sizeof(CONF_SECTION));
}
}
- if ((*cs)->name1)
+ if ((*cs)->name1)
free((*cs)->name1);
- if ((*cs)->name2)
+ if ((*cs)->name2)
free((*cs)->name2);
/*
static void cf_item_add(CONF_SECTION *cs, CONF_ITEM *ci_new)
{
CONF_ITEM *ci;
-
+
for (ci = cs->children; ci && ci->next; ci = ci->next)
;
const char *end, *ptr;
char name[8192];
CONF_SECTION *parentcs;
-
+
/*
* Find the master parent conf section.
* We can't use mainconfig.config, because we're in the
cf, *lineno);
return NULL;
}
-
+
ptr += 2;
-
+
cp = NULL;
up = 0;
up = 1;
cs = outercs;
ptr++;
-
+
/*
* ${..foo} means "foo from the section
* enclosing this section" (etc.)
*/
if (*ptr == '.') {
CONF_SECTION *next;
-
+
ptr++; /* skip the period */
-
+
/*
* Find the sub-section.
*/
return NULL;
}
cs = next;
-
+
} else { /* no period, must be a conf-part */
/*
* Find in the current referenced
}
}
} /* until cp is non-NULL */
-
+
/*
* Substitute the value of the variable.
*/
cf, *lineno);
return NULL;
}
-
+
memcpy(name, ptr, end - ptr);
name[end - ptr] = '\0';
-
+
/*
* Get the environment variable.
* If none exists, then make it an empty string.
*(p++) = *(ptr++);
}
} /* loop over all of the input string. */
-
+
*p = '\0';
return output;
if (cp) {
value = cp->value;
}
-
+
switch (variables[i].type)
{
case PW_TYPE_SUBSECTION:
variables[i].name,
*(int *)data);
break;
-
+
case PW_TYPE_STRING_PTR:
q = (char **) data;
if (*q != NULL) {
value, ip_ntoa(buffer, ipaddr));
*(uint32_t *) data = ipaddr;
break;
-
+
default:
radlog(L_ERR, "type %d not supported yet", variables[i].type);
return -1;
break;
} /* switch over variable type */
} /* for all variables in the configuration section */
-
+
return 0;
}
int t1, t2, t3;
char *cbuf = buf;
int len;
-
+
/*
* Ensure that the user can't add CONF_SECTIONs
* with 'internal' names;
/*
* Allow for $INCLUDE files
*
- * This *SHOULD* work for any level include.
+ * This *SHOULD* work for any level include.
* I really really really hate this file. -cparker
*/
if (strcasecmp(buf1, "$INCLUDE") == 0) {
if (is != NULL) {
if (is->children != NULL) {
CONF_ITEM *ci;
-
+
/*
* Re-write the parent of the
* moved children to be the
/*
* Ignore semi-colons.
*/
- if (*buf2 == ';')
+ if (*buf2 == ';')
*buf2 = '\0';
/*
*/
if (buf1[0] != 0 && buf2[0] == 0 && buf3[0] == 0) {
t2 = T_OP_EQ;
- } else if (buf1[0] == 0 || buf2[0] == 0 ||
+ } else if (buf1[0] == 0 || buf2[0] == 0 ||
(t2 < T_EQSTART || t2 > T_EQEND)) {
radlog(L_ERR, "%s[%d]: Line is not in 'attribute = value' format",
cf, *lineno);
/*
* Read the config file.
*/
-CONF_SECTION *conf_read(const char *fromfile, int fromline,
+CONF_SECTION *conf_read(const char *fromfile, int fromline,
const char *conffile, CONF_SECTION *parent)
{
FILE *fp;
int lineno = 0;
CONF_SECTION *cs;
-
+
if ((fp = fopen(conffile, "r")) == NULL) {
if (fromfile) {
radlog(L_ERR|L_CONS, "%s[%d]: Unable to open file \"%s\": %s",
}
-/*
+/*
* Return a CONF_PAIR within a CONF_SECTION.
*/
CONF_PAIR *cf_pair_find(CONF_SECTION *section, const char *name)
return (section ? section->name2 : NULL);
}
-/*
+/*
* Find a value in a CONF_SECTION
*/
char *cf_section_value_find(CONF_SECTION *section, const char *attr)
for (; ci; ci = ci->next) {
if (ci->type != CONF_ITEM_SECTION)
continue;
- if ((name1 == NULL) ||
+ if ((name1 == NULL) ||
(strcmp(cf_itemtosection(ci)->name1, name1) == 0))
break;
}
#if 0
-/*
+/*
* JMG dump_config tries to dump the config structure in a readable format
- *
+ *
*/
static int dump_config_section(CONF_SECTION *cs, int indent)
*/
radius_xlat(answer, sizeof(answer), cmd, request, NULL);
buf = answer;
-
+
/*
* Log the command if we are debugging something
*/
DEBUG("Exec-Program: %s", buf);
-
+
/*
* Build vector list of arguments and execute.
*
int envlen;
char buffer[1024];
- /*
+ /*
* Child process.
*
* We try to be fail-safe here. So if ANYTHING
strerror(errno));
exit(1);
}
-
+
/*
* pd[1] is the FD that the child will write to,
* so we make it STDOUT.
* more useful...
*/
if ((fp = fopen(file, "r")) == NULL) {
- if (!complain)
+ if (!complain)
return -1;
radlog(L_CONS|L_ERR, "Couldn't open %s for reading: %s",
file, strerror(errno));
* of entries. Go to the end of the
* list.
*/
- while (*last)
+ while (*last)
last = &((*last)->next);
continue;
}
if (realm == NULL) {
realm = "NULL";
}
-
+
for (cl = mainconfig.realms; cl; cl = cl->next) {
/*
* Wake up any sleeping realm.
}
}
- /* If we didn't find the realm 'NULL' don't return the
+ /* If we didn't find the realm 'NULL' don't return the
* DEFAULT entry.
*/
if ((strcmp(realm, "NULL")) == 0) {
REALM *realm_findbyaddr(uint32_t ipaddr, int port)
{
REALM *cl;
-
+
/*
* Note that we do NOT check for inactive realms!
*
return 0;
}
- if (debug_flag
+ if (debug_flag
|| (radlog_dest == RADLOG_STDOUT)
|| (radlog_dir == NULL)) {
msgfd = stdout;
} else if ((msgfd = fopen(mainconfig.log_file, "a")) == NULL) {
fprintf(stderr, "%s: Couldn't open %s for logging: %s\n",
progname, mainconfig.log_file, strerror(errno));
-
+
fprintf(stderr, " (");
vfprintf(stderr, fmt, ap); /* the message that caused the log */
fprintf(stderr, ")\n");
*p = '?';
}
strcat(buffer, "\n");
-
+
/*
* If we're debugging, for small values of debug, then
* we don't do timestamps.
/*
* Dump a whole list of attributes to DEBUG2
- */
+ */
void vp_listdebug(VALUE_PAIR *vp)
-{
- char tmpPair[70];
+{
+ char tmpPair[70];
for (; vp; vp = vp->next) {
vp_prints(tmpPair, sizeof(tmpPair), vp);
DEBUG2(" %s", tmpPair);
- }
+ }
}
-
-
-
+
+
+
* files.
*/
{ "prefix", PW_TYPE_STRING_PTR, 0, &prefix, "/usr/local"},
- { "localstatedir", PW_TYPE_STRING_PTR, 0, &localstatedir, "${prefix}/var"},
+ { "localstatedir", PW_TYPE_STRING_PTR, 0, &localstatedir, "${prefix}/var"},
{ "logdir", PW_TYPE_STRING_PTR, 0, &radlog_dir, "${localstatedir}/log"},
{ "libdir", PW_TYPE_STRING_PTR, 0, &radlib_dir, "${prefix}/lib"},
{ "radacctdir", PW_TYPE_STRING_PTR, 0, &radacct_dir, "${logdir}/radacct" },
outlen = strlen(value) + 1;
}
}
-
+
return func(out, outlen, value);
}
return(0);
}
-
+
/*
* Checks if the log directory is writeable by a particular user.
*/
if (strstr(radlog_dir, "radius") == NULL)
return(0);
- /* we have a logdir that mentions 'radius', so it's probably
- * safe to chown the immediate directory to be owned by the normal
+ /* we have a logdir that mentions 'radius', so it's probably
+ * safe to chown the immediate directory to be owned by the normal
* process owner. we gotta do it before we give up root. -chad
*/
-
+
if (!effectiveuser) {
return 1;
}
static int switch_users(void) {
-
+
/*
* Switch UID and GID to what is specified in the config file
*/
}
-/*
+/*
* Create the linked list of realms from the new configuration type
* This way we don't have to change to much in the other source-files
*/
}
}
- /*
+ /*
* Double check length, just to be sure!
*/
if (strlen(authhost) >= sizeof(c->server)) {
} else {
if ((s = strchr(accthost, ':')) != NULL) {
*s++ = 0;
- c->acct_port = atoi(s);
+ c->acct_port = atoi(s);
} else {
c->acct_port = acct_port;
}
accthost);
return -1;
}
- }
+ }
if (strlen(accthost) >= sizeof(c->acct_server)) {
radlog(L_ERR, "%s[%d]: Server name of length %d is greater than allowed: %d",
(int) sizeof(c->server) - 1);
return -1;
}
-
+
strcpy(c->realm, name2);
if (authhost) strcpy(c->server, authhost);
- if (accthost) strcpy(c->acct_server, accthost);
+ if (accthost) strcpy(c->acct_server, accthost);
/*
* If one or the other of authentication/accounting
filename, cf_section_lineno(cs), name2);
return -1;
}
-
+
if (strlen(s) >= sizeof(c->secret)) {
radlog(L_ERR, "%s[%d]: Secret of length %d is greater than the allowed maximum of %d.",
filename, cf_section_lineno(cs),
}
c->striprealm = 1;
-
+
if ((cf_section_value_find(cs, "nostrip")) != NULL)
c->striprealm = 0;
if ((cf_section_value_find(cs, "noacct")) != NULL)
char *name2;
for (cs = cf_subsection_find_next(mainconfig.config, NULL, "client");
- cs != NULL;
+ cs != NULL;
cs = cf_subsection_find_next(mainconfig.config, cs, "client")) {
name2 = cf_section_name2(cs);
}
if((nastype = cf_section_value_find(cs, "nastype")) != NULL) {
- if(strlen(nastype) >= sizeof(c->nastype)) {
+ if(strlen(nastype) >= sizeof(c->nastype)) {
radlog(L_ERR, "%s[%d]: nastype of length %d longer than the allowed maximum of %d",
- filename, cf_section_lineno(cs),
+ filename, cf_section_lineno(cs),
strlen(nastype), sizeof(c->nastype) - 1);
return -1;
}
}
if((login = cf_section_value_find(cs, "login")) != NULL) {
- if(strlen(login) >= sizeof(c->login)) {
+ if(strlen(login) >= sizeof(c->login)) {
radlog(L_ERR, "%s[%d]: login of length %d longer than the allowed maximum of %d",
- filename, cf_section_lineno(cs),
+ filename, cf_section_lineno(cs),
strlen(login), sizeof(c->login) - 1);
return -1;
}
}
if((password = cf_section_value_find(cs, "password")) != NULL) {
- if(strlen(password) >= sizeof(c->password)) {
+ if(strlen(password) >= sizeof(c->password)) {
radlog(L_ERR, "%s[%d]: password of length %d longer than the allowed maximum of %d",
- filename, cf_section_lineno(cs),
+ filename, cf_section_lineno(cs),
strlen(password), sizeof(c->password) - 1);
return -1;
}
filename, cf_section_lineno(cs), netmask + 1);
return -1;
}
-
+
c->netmask = (1 << 31);
for (i = 1; i < mask_length; i++) {
c->netmask |= (c->netmask >> 1);
}
librad_debug = debug_flag;
old_debug_level = mainconfig.debug_level;
-
+
/*
* Go update our behaviour, based on the configuration
* changes.
limits.rlim_cur = 0;
limits.rlim_max = core_limits.rlim_max;
-
+
if (setrlimit(RLIMIT_CORE, &limits) < 0) {
radlog(L_ERR|L_CONS, "Cannot disable core dumps: %s",
strerror(errno));
* We need root to do mkdir() and chown(), so we
* do this before giving up root.
*/
- radlogdir_iswritable(mainconfig.uid_name);
+ radlogdir_iswritable(mainconfig.uid_name);
}
switch_users();
*/
static void safe_lock(module_instance_t *instance)
{
- if (instance->mutex)
+ if (instance->mutex)
pthread_mutex_lock(instance->mutex);
}
*/
static void safe_unlock(module_instance_t *instance)
{
- if (instance->mutex)
+ if (instance->mutex)
pthread_mutex_unlock(instance->mutex);
}
#else
int myresult = default_result;
DEBUG3(" modsingle[%s]: calling %s (%s) for request %d",
- comp2str[component], sp->modinst->name,
+ comp2str[component], sp->modinst->name,
sp->modinst->entry->name, request->number);
safe_lock(sp->modinst);
myresult = sp->modinst->entry->module->methods[component](
sp->modinst->insthandle, request);
safe_unlock(sp->modinst);
DEBUG3(" modsingle[%s]: returned from %s (%s) for request %d",
- comp2str[component], sp->modinst->name,
+ comp2str[component], sp->modinst->name,
sp->modinst->entry->name, request->number);
return myresult;
node->next = NULL;
node->handle = handle;
strNcpy(node->name, module_name, sizeof(node->name));
-
+
/*
* Link to the module's rlm_FOO{} module structure.
*/
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",
* no name2.
*/
name1 = name2 = NULL;
- for(inst_cs=cf_subsection_find_next(cs, NULL, 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);
node = rad_malloc(sizeof(*node));
node->next = NULL;
node->insthandle = NULL;
-
+
/*
* Link to the module by name: rlm_FOO-major.minor
*/
/* linkto_module logs any errors */
return NULL;
}
-
+
/*
* Call the module's instantiation routine.
*/
node->mutex = NULL;
}
-#endif
+#endif
*last = node;
DEBUG("Module: Instantiated %s (%s) ", name1, node->name);
-
+
return node;
}
/* It is an error to try to create a sublist that already
* exists. It would almost certainly be caused by accidental
* duplication in the config file.
- *
+ *
* index 0 is the exception, because it is used when we want
* to collect _all_ listed modules under a single index by
* default, which is currently the case in all components
const char *modname;
char *visiblename;
- for (modref=cf_item_find_next(cs, NULL);
+ for (modref=cf_item_find_next(cs, NULL);
modref != NULL;
modref=cf_item_find_next(cs, modref)) {
/*
* Set the default list of preloaded symbols.
* This is used to initialize libltdl's list of
- * preloaded modules.
+ * preloaded modules.
*
* i.e. Static modules.
*/
radlog(L_ERR|L_CONS, "Failed to initialize libraries: %s\n",
lt_dlerror());
exit(1); /* FIXME */
-
+
}
/*
* any location on the disk.
*/
lt_dlsetsearchpath(radlib_dir);
-
+
DEBUG2("Module: Library search path is %s",
lt_dlgetsearchpath());
* Allow some old names, too.
*/
if (!next && (comp <= 4)) {
-
+
next = cf_subsection_find_next(cs, sub,
old_section_type_value[comp].typename);
}
if (cf_item_is_section(ci)) {
radlog(L_ERR|L_CONS,
"%s[%d] Subsection for module instantiate is not allowed\n", filename,
-
+
cf_section_lineno(cf_itemtosection(ci)));
exit(1);
}
-
+
cp = cf_itemtopair(ci);
name = cf_pair_attr(cp);
module = find_module_instance(name);
*/
for (comp = 0; comp < RLM_COMPONENT_COUNT; ++comp) {
cs = cf_section_find(component_names[comp]);
- if (cs == NULL)
+ if (cs == NULL)
continue;
-
+
if (load_component_section(cs, comp, filename) < 0) {
exit(1);
}
(int) sizeof(nas->nastype) - 1);
return -1;
}
-
+
/*
* It should be OK now, let's create the buffer.
*/
}
/*
- * Find the name of a nas (prefer short name) based on ipaddr,
+ * Find the name of a nas (prefer short name) based on ipaddr,
* store in passed buffer. If NAS is unknown, return dotted quad.
*/
char * nas_name3(char *buf, size_t buflen, uint32_t ipaddr)
{
REALM *cl, *lb;
uint32_t count;
-
+
lb = NULL;
count = 0;
for (cl = mainconfig.realms; cl; cl = cl->next) {
*/
pairadd(&request->packet->vps,
pairmake("Realm", realm->realm, T_OP_EQ));
-
+
/*
* Access-Request: look for LOCAL realm.
* Accounting-Request: look for LOCAL realm.
*/
if (((request->packet->code == PW_AUTHENTICATION_REQUEST) &&
(realm->ipaddr == htonl(INADDR_NONE))) ||
- ((request->packet->code == PW_ACCOUNTING_REQUEST) &&
+ ((request->packet->code == PW_ACCOUNTING_REQUEST) &&
(realm->acct_ipaddr == htonl(INADDR_NONE)))) {
DEBUG2(" WARNING: Cancelling proxy to Realm %s, as the realm is local.",
realm->realm);
return RLM_MODULE_NOOP;
}
-
+
/*
* Allocate the proxy packet, only if it wasn't already
* allocated by a module. This check is mainly to support
vps = paircopy(request->packet->vps);
namepair = pairfind(vps, PW_USER_NAME);
strippednamepair = pairfind(vps, PW_STRIPPED_USER_NAME);
-
+
/*
* If there's a Stripped-User-Name attribute in
* the request, then use THAT as the User-Name
* Proxied requests get sent out the proxy FD ONLY.
*/
request->proxy->sockfd = proxyfd;
-
+
request->proxy->code = request->packet->code;
if (request->packet->code == PW_AUTHENTICATION_REQUEST) {
request->proxy->dst_port = realm->auth_port;
static void usage(void)
{
fprintf(stderr, "Usage: radclient [options] server[:port] <command> [<secret>]\n");
-
+
fprintf(stderr, " <command> One of auth, acct, status, or disconnect.\n");
fprintf(stderr, " -c count Send each packet 'count' times.\n");
fprintf(stderr, " -d raddb Set dictionary directory.\n");
assert(radclient_head == radclient);
radclient_head = next;
}
-
+
if (next) {
assert(radclient_tail != radclient);
next->prev = prev;
return NULL; /* memory leak "start" */
}
memset(radclient, 0, sizeof(*radclient));
-
+
radclient->request = rad_alloc(1);
if (!radclient->request) {
librad_perror("radclient: ");
radclient_free(radclient);
return NULL; /* memory leak "start" */
}
-
+
radclient->filename = filename;
radclient->request->id = -1; /* allocate when sending */
radclient->packet_number = packet_number++;
-
+
/*
* Read the VP's.
*/
radclient_free(radclient);
return NULL; /* memory leak "start" */
}
-
+
/*
* Keep a copy of the the User-Password attribute.
*/
} else {
radclient->password[0] = '\0';
}
-
+
/*
* Fix up Digest-Attributes issues
*/
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:
prev = radclient;
}
} while (!filedone); /* loop until the file is done. */
-
+
if (fp != stdin) fclose(fp);
-
+
/*
* And we're done.
*/
if (!radclient) {
exit(1);
}
-
+
if (!radclient_head) {
assert(radclient_tail == NULL);
radclient_head = radclient;
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 ((vp = pairfind(radclient->request->vps, PW_PASSWORD)) != NULL) {
strNcpy((char *)vp->strvalue, radclient->password, strlen(radclient->password) + 1);
vp->length = strlen(radclient->password);
-
+
} else if ((vp = pairfind(radclient->request->vps, PW_CHAP_PASSWORD)) != NULL) {
strNcpy((char *)vp->strvalue, radclient->password, strlen(radclient->password) + 1);
vp->length = strlen(radclient->password);
-
+
rad_chap_encode(radclient->request, (char *) vp->strvalue, radclient->request->id, vp);
vp->length = 17;
}
RADIUS_PACKET myrequest, *reply;
rbnode_t *node;
-
+
/* And wait for reply, timing out as necessary */
FD_ZERO(&set);
FD_SET(sockfd, &set);
-
+
if (wait_time <= 0) {
tv.tv_sec = 0;
} else {
tv.tv_sec = wait_time;
}
tv.tv_usec = 0;
-
+
/*
* No packet was received.
*/
if (select(sockfd + 1, &set, NULL, NULL, &tv) != 1) {
return 0;
}
-
+
/*
* Look for the packet.
*/
while ((c = getopt(argc, argv, "c:d:f:hi:qst:r:S:xv")) != EOF) switch(c) {
case 'c':
- if (!isdigit((int) *optarg))
+ if (!isdigit((int) *optarg))
usage();
resend_count = atoi(optarg);
break;
librad_debug++;
break;
case 'r':
- if (!isdigit((int) *optarg))
+ if (!isdigit((int) *optarg))
usage();
retries = atoi(optarg);
break;
case 'i':
- if (!isdigit((int) *optarg))
+ if (!isdigit((int) *optarg))
usage();
id = atoi(optarg);
if ((id < 0) || (id > 255)) {
do_summary = 1;
break;
case 't':
- if (!isdigit((int) *optarg))
+ if (!isdigit((int) *optarg))
usage();
timeout = atof(optarg);
break;
/*
* Walk over the packets, sending them.
*/
-
+
for (this = radclient_head; this != NULL; this = next) {
next = this->next;
-/*
+/*
* radius_snmp.c Radius SNMP support
*
* Version: $Id$
size_t *var_len,
WriteMethod **write_method);
-static struct variable radiusacc_variables[] =
+static struct variable radiusacc_variables[] =
{
{RADIUSACCSERVIDENT, STRING, RONLY, radAccServ, 1, {1}},
{RADIUSACCSERVUPTIME, TIMETICKS, RONLY, radAccServ, 1, {2}},
}
static int
-radServReset (int action, u_char *var_val, u_char var_val_type,
+radServReset (int action, u_char *var_val, u_char var_val_type,
size_t var_val_len, const unsigned char *statP, oid *name,
size_t name_len) {
switch (action) {
case RESERVE1:
- if (var_val_type != INTEGER)
+ if (var_val_type != INTEGER)
return SNMP_ERR_WRONGTYPE;
- if (var_val_len != sizeof (long))
+ if (var_val_len != sizeof (long))
return SNMP_ERR_WRONGLENGTH;
if (! asn_parse_int(var_val, &big, &var_val_type, &i, sizeof(long)))
return SNMP_ERR_WRONGENCODING;
- if (i != 2)
+ if (i != 2)
return SNMP_ERR_WRONGVALUE;
break;
case COMMIT:
}
static const unsigned char *
-radAccServ(struct variable *vp, oid *name, size_t *length, int exact,
+radAccServ(struct variable *vp, oid *name, size_t *length, int exact,
size_t *var_len, WriteMethod **write_method) {
static int result;
}
static const unsigned char *
-radAccEntry(struct variable *vp, oid *name, size_t *length, int exact,
+radAccEntry(struct variable *vp, oid *name, size_t *length, int exact,
size_t *var_len, WriteMethod **write_method) {
RADCLIENT *c;
}
static const unsigned char *
-radAuthServ(struct variable *vp, oid *name, size_t *length, int exact,
+radAuthServ(struct variable *vp, oid *name, size_t *length, int exact,
size_t *var_len, WriteMethod **write_method) {
static int result;
}
static const unsigned char *
-radAuthEntry(struct variable *vp, oid *name, size_t *length, int exact,
+radAuthEntry(struct variable *vp, oid *name, size_t *length, int exact,
size_t *var_len, WriteMethod **write_method) {
RADCLIENT *c;
* Parse the SNMP configuration information.
*/
cs = cf_section_find(NULL);
- if (cs != NULL)
+ if (cs != NULL)
cf_section_parse(cs, NULL, snmp_config);
/*
progname, s);
exit(1);
}
-
+
/* this should never be reached */
return LOG_DAEMON;
}
RAD_SNMP_INC(rad_snmp.auth.total_unknown_types);
radlog(L_ERR, "Unknown packet code %d from client %s:%d "
- "- ID %d : IGNORED", packet->code,
+ "- ID %d : IGNORED", packet->code,
client_name(packet->src_ipaddr),
- packet->src_port, packet->id);
+ packet->src_port, packet->id);
return NULL;
break;
} /* switch over packet types */
-
+
/*
* Don't handle proxy replies here. They need to
* return the *old* request, so we can re-process it.
*/
if (mainconfig.max_requests) {
int request_count = rl_num_requests();
-
+
/*
* This is a new request. Let's see if
* it makes us go over our configured
*/
if (request_count > mainconfig.max_requests) {
radlog(L_ERR, "Dropping request (%d is too many): "
- "from client %s:%d - ID: %d", request_count,
+ "from client %s:%d - ID: %d", request_count,
client_name(packet->src_ipaddr),
packet->src_port, packet->id);
radlog(L_INFO, "WARNING: Please check the radiusd.conf file.\n"
return fun;
}
-
+
/*
* The current request isn't finished, which
* means that the NAS sent us a new packet, while
*/
if (!mainconfig.proxy_synchronous) {
RAD_SNMP_FD_INC(packet->sockfd, total_packets_dropped);
-
+
DEBUG2("Ignoring duplicate packet from client "
"%s:%d - ID: %d, due to outstanding proxied request %d.",
client_name(packet->src_ipaddr),
*/
} else {
char buffer[64];
-
+
DEBUG2("Sending duplicate proxied request to home server %s:%d - ID: %d",
ip_ntoa(buffer, curreq->proxy->dst_ipaddr),
curreq->proxy->dst_port,
-
+
curreq->proxy->id);
}
curreq->proxy_next_try = time_now + mainconfig.proxy_retry_delay;
rad_send(curreq->reply, curreq->packet, curreq->secret);
return NULL;
}
-
+
/*
* Maybe we've saved a reply packet. If so,
* re-send it. Otherwise, just complain.
packet->src_port, packet->id);
return NULL;
} /* else the vectors were different, so we discard the old request. */
-
+
/*
* 'packet' has the same source IP, source port, code,
* and Id as 'curreq', but a different authentication
* if the first reply got lost in the network.
*/
rl_delete(curreq);
-
+
/*
* The request is OK. We can process it...
*
REALM *cl;
REQUEST *oldreq;
char buffer[32];
-
+
/*
* Find the original request in the request list
*/
oldreq->number);
return NULL;
}
-
+
/*
* If there is already a reply, maybe this one is a
* duplicate?
! */
DEBUG2("Ignoring conflicting proxy reply");
}
-
+
/*
* We've already received a reply, so
* we discard this one, as we don't want
* reply packet to it.
*/
rad_assert(request->reply != NULL);
-
+
} else { /* remember the new request */
/*
* A unique per-request counter.
if (radacct_dir) xfree(radacct_dir);
radacct_dir = strdup(optarg);
break;
-
+
case 'c':
/* ignore for backwards compatibility with Cistron */
break;
if (radius_dir) xfree(radius_dir);
radius_dir = strdup(optarg);
break;
-
+
case 'f':
dont_fork = TRUE;
break;
exit(1);
}
break;
-
+
case 'l':
radlog_dir = strdup(optarg);
break;
-
+
/*
* We should also have this as a configuration
* file directive.
case 'x':
debug_flag++;
break;
-
+
case 'y':
mainconfig.log_auth = TRUE;
mainconfig.log_auth_badpass = TRUE;
if (radius_port != 0) {
auth_port = radius_port;
} /* else auth_port is set from the config file */
-
+
/*
* Maybe auth_port *wasn't* set from the config file,
* or the config file set it to zero.
* there, too.
*/
svp = getservbyname ("radacct", "udp");
- if (svp != NULL)
+ if (svp != NULL)
acct_port = ntohs(svp->s_port);
} else {
auth_port = PW_AUTH_UDP_PORT;
* If we haven't already gotten acct_port from /etc/services,
* then make it auth_port + 1.
*/
- if (acct_port == 0)
+ if (acct_port == 0)
acct_port = auth_port + 1;
-
+
acctfd = socket (AF_INET, SOCK_DGRAM, 0);
if (acctfd < 0) {
perror ("acct socket");
perror ("proxy socket");
exit(1);
}
-
+
sa = (struct sockaddr_in *) &salocal;
memset((char *) sa, '\0', sizeof(salocal));
sa->sin_family = AF_INET;
sa->sin_addr.s_addr = mainconfig.myip;
-
+
/*
* Set the proxy port to be one more than the
* accounting port.
break;
}
}
-
+
/*
* Couldn't find a port to which we could bind.
*/
*/
if (debug_flag == FALSE) {
int devnull;
-
+
devnull = open("/dev/null", O_RDWR);
if (devnull < 0) {
radlog(L_ERR|L_CONS, "Failed opening /dev/null: %s\n",
* Use linebuffered or unbuffered stdout if
* the debug flag is on.
*/
- if (debug_flag == TRUE)
+ if (debug_flag == TRUE)
setlinebuf(stdout);
if (mainconfig.myip == INADDR_ANY) {
* handlers. Before this, if we get any signal, we don't know
* what to do, so we might as well do the default, and die.
*/
- signal(SIGPIPE, SIG_IGN);
+ signal(SIGPIPE, SIG_IGN);
#ifdef HAVE_SIGACTION
act.sa_handler = sig_hup;
sigaction(SIGHUP, &act, NULL);
* Detach any modules.
*/
detach_modules();
-
+
/*
* FIXME: clean up any active REQUEST
* handles.
(rad_snmp.smux_event == SMUX_READ)) {
smux_read();
}
-
+
/*
* If we've got to re-connect, then do so now,
* before calling select again.
thread_pool_clean(time_now);
}
#endif
-
+
} /* loop forever */
}
-/*
+/*
* FIXME: The next two functions should all
* be in a module. But not until we have
* more control over module execution.
if (vp == NULL) {
return -1;
}
-
+
rad_rmspace((char *)vp->strvalue);
vp->length = strlen((char *)vp->strvalue);
DEBUG2("rad_rmspace_pair: %s now '%s'", vp->name, vp->strvalue);
-
+
return 0;
}
const char *secret;
int finished = FALSE;
int reprocess = 0;
-
+
/*
* Put the decoded packet into it's proper place.
*/
}
rad_assert(request->magic == REQUEST_MAGIC);
-
+
/*
* Decode the packet, verifying it's signature,
* and parsing the attributes into structures.
request_reject(request);
goto finished_request;
}
-
+
/*
* For proxy replies, remove non-allowed
* attributes from the list of VP's.
request->options |= RAD_REQUEST_OPTION_DONT_CACHE;
}
}
-
+
/*
* We should have a User-Name attribute now.
*/
*/
rad_assert(request->magic == REQUEST_MAGIC);
- /*
+ /*
* FIXME: All this lowercase/nospace junk will be moved
* into a module after module failover is fully in place
*
reprocess = 1;
}
-
+
/*
* If we're re-processing the request, re-set it.
*/
(*fun)(request);
}
}
-
+
/*
* Status-Server requests NEVER get proxied.
*/
switch (rcode) {
default:
break;
-
+
/*
* There was an error trying to proxy the request.
* Drop it on the floor.
request_reject(request);
goto finished_request;
break;
-
+
/*
* If the proxy code has handled the request,
* then postpone more processing, until we get
* Need to copy Proxy-State from request->packet->vps
*/
vp = paircopy2(request->packet->vps, PW_PROXY_STATE);
- if (vp != NULL)
+ if (vp != NULL)
pairadd(&(request->reply->vps), vp);
/*
pid_t pid;
sig = sig; /* -Wunused */
-
+
got_child = FALSE;
needs_child_cleanup = 0; /* reset the queued cleanup number */
* Reset the signal handler, if required.
*/
reset_signal(SIGCHLD, sig_cleanup);
-
+
/*
* Wait for the child, without hanging.
*/
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
+ *
* Copyright 2001 Cistron Internet Services B.V.
* Copyright 2002 Simon Ekstrand <simon@routemeister.net>
*
* Acct-Delay-Time value).
* Otherwise the radius server may consider the
* packet a duplicate and we 'll get caught in a
- * loop.
+ * loop.
*/
if (r->retrans > 0){
id_map[r->req->id] = 0;
/*
* Header above output and format.
*/
-static const char *hdr1 =
+static const char *hdr1 =
"Login Name What TTY When From Location";
static const char *ufmt1 = "%-10.10s %-17.17s %-5.5s %-4.4s %-9.9s %-9.9s %-.16s%s";
static const char *ufmt1r = "%s,%s,%s,%s,%s,%s,%s%s";
static const char *rfmt1 = "%-10.10s %-17.17s %-5.5s %s%-3d %-9.9s %-9.9s %-.19s%s";
static const char *rfmt1r = "%s,%s,%s,%s%d,%s,%s,%s%s";
-static const char *hdr2 =
+static const char *hdr2 =
"Login Port What When From Location";
static const char *ufmt2 = "%-10.10s %-6.6d %-7.7s %-13.13s %-10.10s %-.16s%s";
static const char *ufmt2r = "%s,%d,%s,%s,%s,%s%s";
fp = safe_popen(fn, "r");
} else fp = fopen(fn, "r");
- if (fp == NULL)
+ if (fp == NULL)
return -1;
while(fgets(fn, 1024, fp)) {
if (showlocal && (fp = fopen(radutmp_file, "r"))) {
if (rawoutput == 0)
- {
+ {
fputs(showname ? hdr1 : hdr2, stdout);
fputs(eol, stdout);
}
proto(rt.proto, rt.porttype),
dotime(rt.time),
nas_name3(nasname, sizeof(nasname), rt.nas_address),
- hostname(othername, sizeof(othername), rt.framed_address),
+ hostname(othername, sizeof(othername), rt.framed_address),
eol);
}
}
fprintf(stderr, " [port] Terminal Server port to match\n");
fprintf(stderr, " [user] Login account to match\n");
exit(1);
-}
+}
/*
/* Process the options. */
while ((argval = getopt(argc, argv, "d:p:r:")) != EOF) {
-
+
switch(argval) {
-
+
case 'd':
if (radius_dir) free(radius_dir);
radius_dir = strdup(optarg);
case 'p':
acct_port = atoi(optarg);
break;
-
+
case 'r':
if ((radiusip = ip_getaddr(optarg)) == INADDR_NONE) {
fprintf(stderr, "%s: %s: radius server unknown\n",
exit(1);
}
break;
-
+
default:
usage();
exit(1);
exit(1);
}
}
- if (nas != NULL)
+ if (nas != NULL)
ip = nas->ipaddr;
/*
printf("%s: zapping termserver %s, port %u",
progname, ip_hostname(buf, sizeof(buf), ip), nas_port);
- if (user != NULL)
+ if (user != NULL)
printf(", user %s", user);
printf("\n");
req->id = getpid() & 0xFF;
req->code = PW_ACCOUNTING_REQUEST;
req->dst_port = acct_port;
- if(req->dst_port == 0)
+ if(req->dst_port == 0)
req->dst_port = getport("radacct");
- if(req->dst_port == 0)
+ 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)
+ if(!req->dst_ipaddr)
req->dst_ipaddr = 0x7f000001;
req->vps = NULL;
secret = getsecret(req->dst_ipaddr);
/*
* We keep the incoming requests in an array, indexed by ID.
*
- * Each array element contains a linked list of containers of
- * active requests, a count of the number of requests, and a time
+ * Each array element contains a linked list of containers of
+ * active requests, a count of the number of requests, and a time
* at which the first request in the list must be serviced.
*/
request_list[i].request_count = 0;
request_list[i].last_cleaned_list = 0;
}
-
+
#ifdef WITH_RBTREE
request_tree = rbtree_create(request_cmp, NULL, 0);
if (!request_tree) {
prev = ((REQNODE *) request->container)->prev;
next = ((REQNODE *) request->container)->next;
-
+
id = request->packet->id;
/*
if (last_request == request) {
last_request = rl_next(last_request);
}
-
+
if (prev == NULL) {
request_list[id].first_request = next;
} else {
next->prev = prev;
}
-
+
free(request->container);
#ifdef WITH_SNMP
/*
* Look up a particular request, using:
*
- * Request ID, request code, source IP, source port,
+ * Request ID, request code, source IP, source port,
*
* Note that we do NOT use the request vector to look up requests.
*
{
#ifdef WITH_RBTREE
REQUEST myrequest;
-
+
myrequest.packet = packet;
-
+
return rbtree_finddata(request_tree, &myrequest);
#else
REQNODE *curreq;
REQUEST myrequest, *maybe = NULL;
RADIUS_PACKET myproxy;
rbnode_t *node;
-
+
myrequest.proxy = &myproxy;
-
+
myproxy.id = packet->id;
-
+
/*
* FIXME: Look for BOTH src/dst stuff.
*/
myproxy.dst_ipaddr = packet->src_ipaddr;
myproxy.dst_port = packet->src_port;
-
+
pthread_mutex_lock(&proxy_mutex);
node = rbtree_find(proxy_tree, &myrequest);
if (node) {
#else
REQNODE *curreq = NULL;
int id;
-
+
/*
* The Proxy RADIUS Id is completely independent
* of the original request Id. We've got to root through
for (id = 0; id < 256; id++) {
request_count += request_list[id].request_count;
}
-
+
return request_count;
}
*/
if (request->proxy && !request->proxy_reply) {
rad_assert(request->child_pid == NO_SUCH_CHILD_PID);
-
+
radlog(L_ERR, "Rejecting request %d due to lack of any response from home server %s:%d",
request->number,
client_name(request->packet->src_ipaddr),
pthread_cancel(child_pid);
#endif
} /* else no proxy reply, quietly fail */
-
+
/*
* Maybe we haven't killed it. In that
* case, print a warning.
* It's not yet time to re-send this proxied request.
*/
if (request->proxy_next_try > info->now) goto setup_timeout;
-
+
/*
* If the proxy retry count is zero, then
* we've sent the last try, and have NOT received
*/
request->proxy_try_count--;
request->proxy_next_try = info->now + mainconfig.proxy_retry_delay;
-
+
/* Fix up Acct-Delay-Time */
if (request->proxy->code == PW_ACCOUNTING_REQUEST) {
VALUE_PAIR *delaypair;
delaypair = pairfind(request->proxy->vps, PW_ACCT_DELAY_TIME);
-
+
if (!delaypair) {
delaypair = paircreate(PW_ACCT_DELAY_TIME, PW_TYPE_INTEGER);
if (!delaypair) {
pairadd(&request->proxy->vps, delaypair);
}
delaypair->lvalue = info->now - request->proxy->timestamp;
-
+
/* Must recompile the valuepairs to wire format */
free(request->proxy->data);
request->proxy->data = NULL;
*/
if ((last_tv_ptr != NULL) &&
(last_cleaned_list == now) &&
- (tv.tv_sec != 0)) {
+ (tv.tv_sec != 0)) {
int i;
/*
*
* If there is NO previous request, go look for one.
*/
- if (!last_request)
+ if (!last_request)
last_request = rl_next(last_request);
/*
* And only do this servicing, if we have a request
* to service.
*/
- if (last_request)
+ if (last_request)
for (i = 0; i < mainconfig.cleanup_delay; i++) {
REQUEST *next;
-
+
/*
* This function call MAY delete the
* request pointed to by 'last_request'.
/*
* Nothing to do any more, exit.
*/
- if (!last_request)
+ if (!last_request)
break;
}
* If we ARE proxying, then we can safely sleep
* forever if we're told to NEVER send proxy retries
* ourselves, until the NAS kicks us again.
- *
+ *
* Otherwise, there are no outstanding requests, then
* we can sleep forever. This happens when we get
* woken up with a bad packet. It's discarded, so if
-/*
+/*
* smux.c SNMP support
*
* Version: $Id$
sprintf (buf + strlen (buf), "%s%d", first ? "" : ".", (int) my_oid[i]);
first = 0;
}
- DEBUG2 ("%s: %s", prefix, buf);
+ DEBUG2 ("%s: %s", prefix, buf);
}
static int
#endif /* HAVE_SIN_LEN */
sp = getservbyname ("smux", "tcp");
- if (sp != NULL)
+ if (sp != NULL)
serv.sin_port = sp->s_port;
else
serv.sin_port = htons (SMUX_PORT_DEFAULT);
/* Place holder h1 for complete sequence */
ptr = asn_build_sequence (ptr, &len, (u_char) SMUX_GETRSP, 0);
h1e = ptr;
-
+
ptr = asn_build_int (ptr, &len,
(u_char) (ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
&reqid, sizeof (reqid));
h2 = ptr;
/* Place holder h2 for one variable */
- ptr = asn_build_sequence (ptr, &len,
+ ptr = asn_build_sequence (ptr, &len,
(u_char)(ASN_SEQUENCE | ASN_CONSTRUCTOR),
0);
h2e = ptr;
- ptr = snmp_build_var_op (ptr, objid, &objid_len,
+ ptr = snmp_build_var_op (ptr, objid, &objid_len,
val_type, arg_len, arg, &len);
/* Now variable size is known, fill in size */
asn_build_sequence(h1,&length,(u_char)SMUX_GETRSP,ptr-h1e);
DEBUG2("SMUX getresp send: %d", ptr - buf);
-
+
ret = send (rad_snmp.smux_fd, buf, (ptr - buf), 0);
}
/* Parse header. */
ptr = asn_parse_header (ptr, &len, &type);
-
+
DEBUG2("SMUX var parse: type %d len %d", type, len);
DEBUG2("SMUX var parse: type must be %d", (ASN_SEQUENCE | ASN_CONSTRUCTOR));
/* Parse var option. */
*objid_len = MAX_OID_LEN;
- ptr = snmp_parse_var_op(ptr, objid, objid_len, &val_type,
+ ptr = snmp_parse_var_op(ptr, objid, objid_len, &val_type,
&val_len, &val, &len);
if (var_val_len)
/* Check */
for (l = treelist; l; l=l->next) {
subtree = l->data;
- subresult = oid_compare_part (reqid, *reqid_len,
+ subresult = oid_compare_part (reqid, *reqid_len,
subtree->name, subtree->name_len);
/* Subtree matched. */
}
static int
-smux_getnext (oid *reqid, size_t *reqid_len, int exact,
+smux_getnext (oid *reqid, size_t *reqid_len, int exact,
u_char *val_type, const void **val, size_t *val_len)
{
int j;
for (l = treelist; l; l=l->next) {
subtree = l->data;
- subresult = oid_compare_part (reqid, *reqid_len,
+ subresult = oid_compare_part (reqid, *reqid_len,
subtree->name, subtree->name_len);
/* If request is in the tree. The agent has to make sure we
int ret;
DEBUG2 ("SMUX GET message parse: len %d", len);
-
+
/* Parse GET message header. */
ptr = smux_parse_get_header (ptr, &len, &reqid);
-
+
/* Parse GET message object ID. We needn't the value come */
ptr = smux_var (ptr, len, my_oid, &oid_len, NULL, NULL, NULL);
{
char val;
long errstat;
-
+
ptr = asn_parse_int (ptr, &len, &val, &errstat, sizeof (errstat));
DEBUG2 ("SMUX_RRSP value: %d errstat: %ld", val, errstat);
static int
smux_parse (char *ptr, int len)
{
- /* this buffer we'll use for SOUT message. We could allocate it with malloc and
+ /* this buffer we'll use for SOUT message. We could allocate it with malloc and
save only static pointer/lenght, but IMHO static buffer is a faster solusion */
static u_char sout_save_buff[SMUXMAXPKTSIZE];
static int sout_save_len = 0;
/* SMUX Open. */
smux_proto_version = 0;
- ptr = asn_build_int (ptr, &len,
+ ptr = asn_build_int (ptr, &len,
(u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
&smux_proto_version, sizeof (u_long));
/* SMUX connection oid. */
ptr = asn_build_objid (ptr, &len,
- (u_char)
+ (u_char)
(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_OBJECT_ID),
smux_oid, smux_oid_len);
/* SMUX connection description. */
- ptr = asn_build_string (ptr, &len,
+ ptr = asn_build_string (ptr, &len,
(u_char)
(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_OCTET_STR),
rad_progname, strlen (rad_progname));
/* SMUX connection password. */
- ptr = asn_build_string (ptr, &len,
+ ptr = asn_build_string (ptr, &len,
(u_char)
(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_OCTET_STR),
rad_snmp.smux_password, strlen(rad_snmp.smux_password));
/* Priority. */
priority = -1;
- ptr = asn_build_int (ptr, &len,
+ ptr = asn_build_int (ptr, &len,
(u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
&priority, sizeof (u_long));
/* Operation. */
operation = rad_snmp.snmp_write_access ? 2 : 1; /* Register R/O or R/W */
- ptr = asn_build_int (ptr, &len,
+ ptr = asn_build_int (ptr, &len,
(u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
&operation, sizeof (u_long));
* A mapping of configuration file names to internal integers
*/
static const CONF_PARSER thread_config[] = {
- { "start_servers", PW_TYPE_INTEGER, 0, &thread_pool.start_threads, "5" },
- { "max_servers", PW_TYPE_INTEGER, 0, &thread_pool.max_threads, "32" },
- { "min_spare_servers", PW_TYPE_INTEGER, 0, &thread_pool.min_spare_threads, "3" },
- { "max_spare_servers", PW_TYPE_INTEGER, 0, &thread_pool.max_spare_threads, "10" },
- { "max_requests_per_server", PW_TYPE_INTEGER, 0, &thread_pool.max_requests_per_thread, "0" },
- { "cleanup_delay", PW_TYPE_INTEGER, 0, &thread_pool.cleanup_delay, "5" },
+ { "start_servers", PW_TYPE_INTEGER, 0, &thread_pool.start_threads, "5" },
+ { "max_servers", PW_TYPE_INTEGER, 0, &thread_pool.max_threads, "32" },
+ { "min_spare_servers", PW_TYPE_INTEGER, 0, &thread_pool.min_spare_threads, "3" },
+ { "max_spare_servers", PW_TYPE_INTEGER, 0, &thread_pool.max_spare_threads, "10" },
+ { "max_requests_per_server", PW_TYPE_INTEGER, 0, &thread_pool.max_requests_per_thread, "0" },
+ { "cleanup_delay", PW_TYPE_INTEGER, 0, &thread_pool.cleanup_delay, "5" },
{ NULL, -1, 0, NULL, NULL }
};
struct timeval tv;
#ifdef HAVE_PTHREAD_SIGMASK
sigset_t set, old_set;
-
+
/*
* Block a large number of signals which could
* cause the select to return EINTR
for (count = 0; count < 10; count++) {
tv.tv_sec = 0;
tv.tv_usec = 10000; /* sleep for 10 milliseconds */
-
+
/*
* Portable sleep that's thread-safe.
*
ok = TRUE;
break;
}
- }
+ }
#ifdef HAVE_PTHREAD_SIGMASK
/*
sigaddset(&set, SIGTERM);
pthread_sigmask(SIG_BLOCK, &set, NULL);
#endif
-
+
/*
* Loop forever, until told to exit.
*/
DEBUG2("Thread %d handling request %d, (%d handled so far)",
self->thread_num, self->request->number,
self->request_count);
-
+
/*
* Respond, and reset request->child_pid
*/
} else {
prev->next = next;
}
-
+
if (next == NULL) {
rad_assert(thread_pool.tail == handle);
thread_pool.tail = prev;
*/
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
-
+
/*
* Create the thread detached, so that it cleans up it's
* own memory when it exits.
* until all threads are finished handling requests. This returns
* the number of active threads to 'radiusd.c'.
*/
-int total_active_threads(void)
+int total_active_threads(void)
{
int rcode = 0;
THREAD_HANDLE *handle;
-
+
for (handle = thread_pool.head; handle != NULL; handle = handle->next){
if (handle->request != NULL) {
rcode ++;
*/
if (thread_pool.active_threads == thread_pool.total_threads) {
if (spawn_thread(request->timestamp) == NULL) {
- radlog(L_INFO,
- "The maximum number of threads (%d) are active, cannot spawn new thread to handle request",
+ radlog(L_INFO,
+ "The maximum number of threads (%d) are active, cannot spawn new thread to handle request",
thread_pool.max_threads);
return 0;
}
}
}
}
-
+
/*
* Otherwise everything's kosher. There are not too few,
* or too many spare threads. Exit happily.
void rad_exec_init(void)
{
int i;
-
+
/*
* Initialize the mutex used to remember calls to fork.
*/
pthread_mutex_init(&fork_mutex, NULL);
-
+
/*
* Initialize the data structure where we remember the
* mappings of thread ID && child PID to exit status.
pid_t rad_fork(int exec_wait)
{
sigset_t set;
- pid_t child_pid;
+ pid_t child_pid;
/*
* The thread is NOT interested in waiting for the exit
*/
i = PID_2_ARRAY(child_pid);
found = -1;
-
+
/*
* We may have multiple threads trying to find an
* empty position, so we lock the array until
* That is, we've forked, and the forker
* is waiting nearly forever
*/
- return 0;
+ return 0;
}
i++;
for (hr = tm; *hr; hr++)
if (isdigit((int) *hr))
break;
- if (hr == tm)
+ if (hr == tm)
tm = "Al";
timestr_debug("dayfill: hr %s tm %s\n", hr, tm);
break;
}
- if (tot == 0)
+ if (tot == 0)
return -1;
return (i == now) ? 0 : tot;
return SIG_ERR;
return oact.sa_handler;
#else
-
+
/*
* re-set by calling the 'signal' function, which
* may cause infinite recursion and core dumps due to
*/
struct request_data_t {
request_data_t *next;
-
+
void *unique_ptr;
int unique_int;
void *opaque;
* blow up!
*/
rad_assert(request->child_pid == NO_SUCH_CHILD_PID);
-
- if (request->packet)
+
+ if (request->packet)
rad_free(&request->packet);
- if (request->proxy)
+ if (request->proxy)
rad_free(&request->proxy);
- if (request->reply)
+ if (request->reply)
rad_free(&request->reply);
- if (request->proxy_reply)
+ if (request->proxy_reply)
rad_free(&request->proxy_reply);
- if (request->config_items)
+ if (request->config_items)
pairfree(&request->config_items);
request->username = NULL;
void *rad_malloc(size_t size)
{
void *ptr = malloc(size);
-
+
if (ptr == NULL) {
radlog(L_ERR|L_CONS, "no memory");
exit(1);
vps = packet->vps;
packet->vps = NULL;
break;
-
+
/*
* Accounting responses can only contain
* Proxy-State and VSA's. Note that we do NOT
if (request->options & RAD_REQUEST_OPTION_REJECTED) {
return;
}
-
+
DEBUG2("Server rejecting request %d.", request->number);
switch (request->packet->code) {
/*
* reject message sent.
*/
case PW_AUTHENTICATION_REQUEST:
- request->reply->code = PW_AUTHENTICATION_REJECT;
+ request->reply->code = PW_AUTHENTICATION_REJECT;
/*
* Perform RFC limitations on outgoing replies.
pairadd(&(request->reply->vps), vps);
break;
}
-
+
/*
* If a reply exists, send it.
*/
c = rad_malloc(sizeof(struct cmp));
- if (compare_attr < 0)
+ if (compare_attr < 0)
compare_attr = attr;
c->compare = fun;
c->attribute = attr;
rcode = radius_xlat(buffer, sizeof(buffer),
check_item->strvalue,
req, NULL);
-
+
/*
* Parse the string into a new value.
*/
case T_OP_GT:
if (compare <= 0) result = -1;
break;
-
+
case T_OP_LE:
if (compare > 0) result = -1;
break;
return 0;
}
s = strtok(NULL, ",");
- }
+ }
return -1;
}
/*
* Compare prefix/suffix.
*
- * If they compare:
+ * If they compare:
* - if PW_STRIP_USER_NAME is present in check_pairs,
* strip the username of prefix/suffix.
* - if PW_STRIP_USER_NAME is not present in check_pairs,
char rest[MAX_STRING_LEN];
int len, namelen;
int ret = -1;
-
+
instance = instance;
reply_pairs = reply_pairs; /* shut the compiler up */
* and have one less system call to do.
*/
static int timecmp(void *instance,
- REQUEST *req UNUSED,
+ REQUEST *req UNUSED,
VALUE_PAIR *request, VALUE_PAIR *check,
VALUE_PAIR *check_pairs, VALUE_PAIR **reply_pairs)
{
rcode = radius_xlat(buffer, sizeof(buffer),
i->strvalue,
req, NULL);
-
+
/*
* Parse the string into a new value.
*/
found = pairfind(*to, i->attribute);
switch (i->operator) {
-
+
/*
* If a similar attribute is found,
* delete it.
(strcmp((char *)found->strvalue,
(char *)i->strvalue) == 0)){
pairdelete(to, found->attribute);
-
+
/*
* 'tailto' may have been
* deleted...
tailfrom = i;
continue;
break;
-
+
/*
* Add it, if it's not already there.
*/
continue; /* with the loop */
}
break;
-
+
/*
* If a similar attribute is found,
* replace it with the new one. Otherwise,
continue;
}
break;
-
+
/*
* FIXME: Add support for <=, >=, <, >
*
* which will mean (for integers)
* 'make the attribute the smaller, etc'
*/
-
+
/*
* Add the new element to the list, even
* if similar ones already exist.
case T_OP_ADD: /* += */
break;
}
-
+
if (tailfrom)
tailfrom->next = next;
else
*from = next;
-
+
/*
* If ALL of the 'to' attributes have been deleted,
* then ensure that the 'tail' is updated to point
/*
- * xlat.c Translate strings. This is the first version of xlat
+ * xlat.c Translate strings. This is the first version of xlat
* incorporated to RADIUS
*
* Version: $Id$
* Copyright 2000 Alan DeKok <aland@ox.org>
*/
-static const char rcsid[] =
+static const char rcsid[] =
"$Id$";
#include "autoconf.h"
{
DICT_ATTR *tmpda;
VALUE_PAIR *vp;
-
+
tmpda = dict_attrbyname(from);
if (!tmpda) return 0;
{
DICT_ATTR *tmpda;
VALUE_PAIR *vp;
-
+
tmpda = dict_attrbyname(from);
if (!tmpda) return 0;
*q = '\0';
- /*
- * Skip the '{' at the front of 'p'
- * Increment open braces
- */
+ /*
+ * Skip the '{' at the front of 'p'
+ * Increment open braces
+ */
p++;
openbraces++;
openbraces++;
*pa++ = *p++;
break;
-
+
case '}':
openbraces--;
if (openbraces == *open) {
/*
* 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
+ * a closing brace and apply it
*/
if ((c == '}') && openbraces) {
openbraces--;
typedef struct rlm_acct_unique_t {
char *key;
- rlm_acct_unique_list_t *head;
+ rlm_acct_unique_list_t *head;
} rlm_acct_unique_t;
static CONF_PARSER module_config[] = {
*/
static void unique_add_attr(rlm_acct_unique_t *inst, DICT_ATTR *dattr)
{
- rlm_acct_unique_list_t *new;
-
+ rlm_acct_unique_list_t *new;
+
new = rad_malloc(sizeof(*new));
memset(new, 0, sizeof(*new));
{
char *ptr, *prev, *keyptr;
DICT_ATTR *a;
-
+
keyptr = key;
ptr = key;
prev = key;
-
+
/* Let's remove spaces in the string */
rad_rmspace(key);
-
+
ptr = key;
while(ptr) {
switch(*ptr) {
continue;
break;
}
- ptr++;
- }
-
+ ptr++;
+ }
+
return 0;
}
*/
inst = rad_malloc(sizeof(*inst));
memset(inst, 0, sizeof(*inst));
-
+
if (cf_section_parse(conf, inst, module_config) < 0) {
free(inst);
return -1;
}
- /*
- * Check to see if 'key' has something in it
- */
+ /*
+ * Check to see if 'key' has something in it
+ */
if (!inst->key) {
radlog(L_ERR,"rlm_acct_unique: Cannot find value for 'key' in configuration.");
free(inst);
return -1;
}
- /*
+ /*
* Go thru the list of keys and build attr_list;
- */
+ */
if (unique_parse_key(inst, inst->key) < 0) {
unique_detach(inst); /* clean up memory */
return -1;
int length, left;
rlm_acct_unique_t *inst = instance;
rlm_acct_unique_list_t *cur;
-
+
/* initialize variables */
p = buffer;
left = BUFFERLEN;
length = 0;
cur = inst->head;
-
+
/*
* A unique ID already exists: don't do anything.
*/
if (vp) {
return RLM_MODULE_NOOP;
}
-
+
/* loop over items to create unique identifiers */
while (cur) {
vp = pairfind(request->packet->vps, cur->dattr->attr);
cur = cur->next;
}
buffer[BUFFERLEN-left-1] = '\0';
-
+
DEBUG2("rlm_acct_unique: Hashing '%s'", buffer);
/* calculate a 'unique' string based on the above information */
librad_md5_calc(md5_buf, (u_char *)buffer, (p - buffer));
sprintf(buffer, "%02x%02x%02x%02x%02x%02x%02x%02x",
md5_buf[0], md5_buf[1], md5_buf[2], md5_buf[3],
md5_buf[4], md5_buf[5], md5_buf[6], md5_buf[7]);
-
+
DEBUG2("rlm_acct_unique: Acct-Unique-Session-ID = \"%s\".", buffer);
-
+
vp = pairmake("Acct-Unique-Session-Id", buffer, 0);
if (!vp) {
radlog(L_ERR, "%s", librad_errstr);
return RLM_MODULE_FAIL;
}
-
+
/* add the (hopefully) unique session ID to the packet */
pairadd(&request->packet->vps, vp);
-
+
return RLM_MODULE_OK;
}
static int always_instantiate(CONF_SECTION *conf, void **instance)
{
rlm_always_t *data;
-
+
/*
* Set up a storage area for instance data
*/
free(data);
return -1;
}
-
+
/*
* Convert the rcode string to an int, and get rid of it
*/
}
module_t rlm_always = {
- "always",
+ "always",
RLM_TYPE_THREAD_SAFE, /* type */
NULL, /* initialization */
always_instantiate, /* instantiation */
* This program is is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, version 2 if the
* License as published by the Free Software Foundation.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
default:
radlog(L_ERR, "Invalid operator for item %s: "
"reverting to '=='", check_item->name);
-
+
case T_OP_CMP_TRUE: /* comp always == 0 */
case T_OP_CMP_FALSE: /* comp always == 1 */
case T_OP_CMP_EQ:
++*(fa);
}
break;
-
+
case T_OP_LE:
if (comp <= 0) {
++*(pa);
if (rcode < 0) {
return -1;
}
-
+
/*
* Walk through the 'attrs' file list.
*/
-
+
entry = attrs;
while (entry) {
-
+
entry->check = entry->reply;
entry->reply = NULL;
-
+
for (vp = entry->check; vp != NULL; vp = vp->next) {
/*
entry->name);
}
}
-
+
entry = entry->next;
}
*/
realmpair = pairfind(request_pairs, PW_REALM);
if(!realmpair) {
- /* Can't find a realm, so no filtering of attributes
+ /* Can't find a realm, so no filtering of attributes
* or should we use a DEFAULT entry?
* For now, just return NOTFOUND. (maybe NOOP?)
*/
}
- /*
+ /*
* Iterate through the reply items, comparing each reply item
- * to every rule, then moving it to the reply_tmp list
+ * to every rule, then moving it to the reply_tmp list
* only if it matches all rules for that attribute.
* IE, Idle-Timeout is moved only if it matches all rules that
- * describe an Idle-Timeout.
+ * describe an Idle-Timeout.
*/
for(reply_item = *reply_items;
compare = simplepaircmp(request, reply_item,
check_item);
- check_pair(check_item, reply_item, compare,
+ check_pair(check_item, reply_item, compare,
&pass, &fail);
}
/* reset the pass/fail vars for each packet->vp. */
pass = fail = 0;
-
+
/* reset the check_item pointer to beginning of the list */
check_item = pl->check;
}
pairfree (&request->packet->vps);
request->packet->vps = send_tmp;
-
+
/*
* See if we succeeded. If we didn't find the realm,
* then exit from the module.
compare = simplepaircmp(request, reply_item,
check_item);
- check_pair(check_item, reply_item, compare,
+ check_pair(check_item, reply_item, compare,
&pass, &fail);
}
return RLM_MODULE_UPDATED;
}
-
+
/*
* Clean up.
*/
char searchin; /* The same as above just coded as a number for speed */
char *replace; /* The replacement */
int replace_len; /* The length of the replacement string */
- int append; /* Switch to control append mode (1,0) */
+ int append; /* Switch to control append mode (1,0) */
int nocase; /* Ignore case */
int new_attr; /* Boolean. Do we create a new attribute or not? */
int num_matches; /* Maximum number of matches */
rlm_attr_rewrite_t *data;
DICT_ATTR *dattr;
char *instance_name = NULL;
-
+
/*
* Set up a storage area for instance data
*/
}
/*
- * Discover the attribute number of the key.
+ * Discover the attribute number of the key.
*/
if (data->attribute == NULL) {
radlog(L_ERR, "rlm_attr_rewrite: 'attribute' must be set.");
instance_name = cf_section_name2(conf);
if (instance_name != NULL)
data->name = strdup(instance_name);
-
-
+
+
*instance = data;
-
+
return 0;
}
len = pmatch.rm_so;
if (data->append) {
len = len + (pmatch.rm_eo - pmatch.rm_so);
- }
+ }
counter += len;
if (counter >= MAX_STRING_LEN) {
regfree(&preg);
DEBUG2("rlm_attr_rewrite: Replacement out of limits for attribute %s with value '%s'",
- data->attribute, attr_vp->strvalue);
+ data->attribute, attr_vp->strvalue);
return ret;
}
if (counter >= MAX_STRING_LEN) {
regfree(&preg);
DEBUG2("rlm_attr_rewrite: Replacement out of limits for attribute %s with value '%s'",
- data->attribute, attr_vp->strvalue);
+ data->attribute, attr_vp->strvalue);
return ret;
}
if (replace_len){
strncpy(ptr, replace_STR, replace_len);
- ptr += replace_len;
+ ptr += replace_len;
}
}
regfree(&preg);
counter += len;
if (counter >= MAX_STRING_LEN){
DEBUG2("rlm_attr_rewrite: Replacement out of limits for attribute %s with value '%s'",
- data->attribute, attr_vp->strvalue);
+ data->attribute, attr_vp->strvalue);
return ret;
}
strncpy(ptr, ptr2, len);
DEBUG2("rlm_attr_rewrite: Added attribute %s with value '%s'",data->attribute,replace_STR);
ret = RLM_MODULE_OK;
}
-
+
return ret;
}
free(data->attribute);
if (data->search)
free(data->search);
- if (data->replace)
+ if (data->replace)
free(data->replace);
if (data->name)
free(data->name);
* is single-threaded.
*/
module_t rlm_attr_rewrite = {
- "attr_rewrite",
+ "attr_rewrite",
RLM_TYPE_THREAD_UNSAFE, /* type */
NULL, /* initialization */
attr_rewrite_instantiate, /* instantiation */
static int chap_authorize(void *instance, REQUEST *request)
{
-
+
/* quiet the compiler */
instance = instance;
request = request;
DEBUG2(" rlm_chap: WARNING: Auth-Type already set. Not setting to CHAP");
return RLM_MODULE_NOOP;
}
-
+
DEBUG(" rlm_chap: Setting 'Auth-Type := CHAP'");
pairadd(&request->config_items,
pairmake("Auth-Type", "CHAP", T_OP_EQ));
return RLM_MODULE_OK;
}
-
+
/*
* Find the named user in this modules database. Create the set
/*
* Don't print out the CHAP password here. It's binary crap.
*/
- DEBUG(" rlm_chap: login attempt by \"%s\" with CHAP password",
+ DEBUG(" rlm_chap: login attempt by \"%s\" with CHAP password",
request->username->strvalue);
if ((passwd_item = pairfind(request->config_items, PW_PASSWORD)) == NULL){
DEBUG(" rlm_chap: Using clear text password %s for user %s authentication.",
passwd_item->strvalue, request->username->strvalue);
-
+
rad_chap_encode(request->packet,pass_str,request->password->strvalue[0],passwd_item);
-
+
if (memcmp(pass_str+1,request->password->strvalue+1,CHAP_VALUE_LENGTH) != 0){
DEBUG(" rlm_chap: Pasword check failed");
snprintf(module_fmsg,sizeof(module_fmsg),"rlm_chap: Wrong user password");
* is single-threaded.
*/
module_t rlm_chap = {
- "CHAP",
+ "CHAP",
0, /* type */
NULL, /* initialization */
NULL, /* instantiation */
#ifdef HAVE_REGEX_H
# include <regex.h>
#endif
-#ifndef REG_EXTENDED
+#ifndef REG_EXTENDED
#define REG_EXTENDED (0)
#endif
-#ifndef REG_NOSUB
+#ifndef REG_NOSUB
#define REG_NOSUB (0)
#endif
/*
{ "binary", PW_TYPE_OCTETS },
{ NULL, 0 }
};
-
+
/*
* Set up a storage area for instance data
*/
return -1;
}
data->item_attr = dattr->attr;
-
+
/*
* Add the check attribute name to the dictionary
* if it does not already exists. dict_addattr() handles that
}
*instance = data;
-
+
return 0;
}
/*
* Look for the check item
*/
-
+
if (!(item_vp = pairfind(request->packet->vps, data->item_attr))){
DEBUG2("rlm_checkval: Could not find item named %s in request", data->item_name);
if (data->notfound_reject)
}
}
else{ /* Integer or Date */
-
+
if (item_vp->lvalue == chk_vp->lvalue)
ret = RLM_MODULE_OK;
else
regerror(err, ®,err_msg, MAX_STRING_LEN);
DEBUG("rlm_checkval: regcomp() returned error: %s", err_msg);
return RLM_MODULE_FAIL;
- }
+ }
if (regexec(®, (char *)item_vp->strvalue,0, NULL, 0) == 0)
ret = RLM_MODULE_OK;
else
char module_fmsg[MAX_STRING_LEN];
VALUE_PAIR *module_fmsg_vp;
- snprintf(module_fmsg,sizeof(module_fmsg),
+ snprintf(module_fmsg,sizeof(module_fmsg),
"rlm_checkval: Could not find item named %s in request", data->item_name);
module_fmsg_vp = pairmake("Module-Failure-Message", module_fmsg, T_OP_EQ);
pairadd(&request->packet->vps, module_fmsg_vp);
* is single-threaded.
*/
module_t rlm_checkval = {
- "checkval",
+ "checkval",
0, /* type */
NULL, /* initialization */
checkval_instantiate, /* instantiation */
/*
* See if the counter matches.
*/
-static int counter_cmp(void *instance,
- REQUEST *req UNUSED,
+static int counter_cmp(void *instance,
+ REQUEST *req UNUSED,
VALUE_PAIR *request, VALUE_PAIR *check,
VALUE_PAIR *check_pairs, VALUE_PAIR **reply_pairs)
{
datum time_datum;
const char *default1 = "DEFAULT1";
const char *default2 = "DEFAULT2";
-
+
DEBUG2("rlm_counter: add_defaults: Start");
key_datum.dptr = (char *) default1;
*/
ret = add_defaults(data);
if (ret != RLM_MODULE_OK)
- return ret;
+ return ret;
DEBUG2("rlm_counter: reset_db ended");
return -1;
}
strftime(sNextTime, sizeof(sNextTime),"%Y-%m-%d %H:%M:%S",tm);
- DEBUG2("rlm_counter: Current Time: %d [%s], Next reset %d [%s]",
+ DEBUG2("rlm_counter: Current Time: %d [%s], Next reset %d [%s]",
(int)timeval,sCurrentTime,(int)data->reset_time,sNextTime);
return ret;
datum time_datum;
const char *default1 = "DEFAULT1";
const char *default2 = "DEFAULT2";
-
+
/*
* Set up a storage area for instance data
*/
cache_size = data->cache_size;
/*
- * Discover the attribute number of the key.
+ * Discover the attribute number of the key.
*/
if (data->key_name == NULL) {
radlog(L_ERR, "rlm_counter: 'key' must be set.");
return -1;
}
data->key_attr = dattr->attr;
-
+
/*
- * Discover the attribute number of the counter.
+ * Discover the attribute number of the counter.
*/
if (data->count_attribute == NULL) {
radlog(L_ERR, "rlm_counter: 'count-attribute' must be set.");
return -1;
}
data->service_val = dval->value;
- }
+ }
/*
* Find when to reset the database.
key_datum.dptr = (char *)default2;
key_datum.dsize = strlen(default2);
- time_datum = gdbm_fetch(data->gdbm, key_datum);
+ time_datum = gdbm_fetch(data->gdbm, key_datum);
if (time_datum.dptr != NULL){
memcpy(&data->last_reset, time_datum.dptr, sizeof(time_t));
free(time_datum.dptr);
pthread_mutex_init(&data->mutex, NULL);
*instance = data;
-
+
return 0;
}
}
}
-
+
/*
* Look for the key. User-Name is special. It means
free(count_datum.dptr);
if (counter.uniqueid)
DEBUG("rlm_counter: Counter Unique ID = '%s'",counter.uniqueid);
- if (uniqueid_vp != NULL){
- if (counter.uniqueid != NULL &&
+ if (uniqueid_vp != NULL){
+ if (counter.uniqueid != NULL &&
strncmp(uniqueid_vp->strvalue,counter.uniqueid, UNIQUEID_MAX_LEN - 1) == 0){
DEBUG("rlm_counter: Unique IDs for user match. Droping the request.");
return RLM_MODULE_NOOP;
*/
counter.user_counter = 0;
-
+
DEBUG("rlm_counter: Searching the database for key '%s'",key_vp->strvalue);
pthread_mutex_lock(&data->mutex);
count_datum = gdbm_fetch(data->gdbm, key_datum);
DEBUG("rlm_counter: res is greater than zero");
if (data->count_attr == PW_ACCT_SESSION_TIME) {
/*
- * Do the following only if the count attribute is
+ * Do the following only if the count attribute is
* AcctSessionTime
*/
snprintf(module_fmsg,sizeof(module_fmsg), "rlm_counter: Maximum %s usage time reached", data->reset);
module_fmsg_vp = pairmake("Module-Failure-Message", module_fmsg, T_OP_EQ);
- pairadd(&request->packet->vps, module_fmsg_vp);
+ pairadd(&request->packet->vps, module_fmsg_vp);
ret=RLM_MODULE_REJECT;
* is single-threaded.
*/
module_t rlm_counter = {
- "Counter",
+ "Counter",
RLM_TYPE_THREAD_SAFE, /* type */
NULL, /* initialization */
counter_instantiate, /* instantiation */
/*
- * rlm_cram.c
+ * rlm_cram.c
*
* Version: $Id$
*
*
* Copyright 2002 The FreeRADIUS server project
*/
-
+
/*
* CRAM mail authentication (APOP, CRAM-MD5)
* by 3APA3A
* for APOP/CRAM-MD5/CRAM-MD4, 20 octets for CRAM-SHA1
*
* (c) 2002 by SANDY (http://www.sandy.ru/) under GPL
- */
+ */
#include "autoconf.h"
#include "libradius.h"
#ifdef SANDY_MOD
char *dms_servers;
char *ducpd_servers;
-#endif
+#endif
char *userfile;
int findmod;
} rlm_dbm_t;
static CONF_PARSER module_config[] = {
- { "usersfile", PW_TYPE_STRING_PTR,offsetof(struct rlm_dbm_t,userfile),
+ { "usersfile", PW_TYPE_STRING_PTR,offsetof(struct rlm_dbm_t,userfile),
NULL, "/etc/uf" },
{ NULL, -1, 0, NULL, NULL }
};
static void sm_user_list_wipe (SM_USER_ENTRY **ue) {
-
+
SM_USER_ENTRY * pue, *nue;
-
+
if ( ! *ue ) return ;
pue = *ue;
-
+
while ( pue != NULL ) {
nue = pue -> next;
DEBUG2("Remove %s from user list", pue -> username);
free(pue -> username);
free(pue);
- pue = nue;
+ pue = nue;
}
*ue = NULL;
}
*/
static int sm_user_list_add(SM_USER_ENTRY **ue, const char *un) {
-
+
while( *ue ) {
- if ( strcmp( (*ue) -> username, un) == 0 ) return 1;
+ if ( strcmp( (*ue) -> username, un) == 0 ) return 1;
ue = & ((*ue) -> next);
}
*ue = malloc(sizeof(SM_USER_ENTRY));
* pdb - ndbm handler
* username - user name from request
* request - pair originated from the nas
- * mode - search mode SM_SM_ACCUM - accumulative search mode
+ * mode - search mode SM_SM_ACCUM - accumulative search mode
* out-parameters:
* in-out:
* parsed_users - list of parsed user names for loop removal
*/
-
+
static int sm_parse_user(DBM *pdb, const char * username, VALUE_PAIR const* request, VALUE_PAIR **config,
VALUE_PAIR **reply, SM_USER_ENTRY **ulist)
{
VALUE_PAIR *vp = NULL,* tmp_config = NULL, *tmp_reply = NULL, *nu_reply = NULL;
VALUE_PAIR *join_attr;
char *ch,*beg;
-
- int parse_state = SMP_PATTERN;
+
+ int parse_state = SMP_PATTERN;
int continue_search = 1;
-
+
/* check for loop */
-
+
DEBUG2("sm_parse_user.c: check for loops");
if ( (retcod = sm_user_list_add(ulist,username) ) ) {
if ( retcod < 0 ) radlog(L_ERR,"rlm_dbm: Couldn't allocate memory");
else radlog(L_ERR,"rlm_dbm: Invalid configuration: loop detected");
- return RLM_MODULE_FAIL;
+ return RLM_MODULE_FAIL;
}
/* retrieve user content */
-
+
k.dptr = username;
k.dsize = strlen(username) + 1 ; /* username stored with '\0' */
-
+
d = dbm_fetch(pdb, k);
if ( d.dptr == NULL ) {
DEBUG2("rlm_dbm: User <%s> not foud in database\n",username);
return RLM_MODULE_NOTFOUND;
}
-
+
ch = d.dptr;
ch [ d.dsize - 1 ] = '\0'; /* should be closed by 0 */
-
+
DEBUG2("sm_parse_user: start parsing: user: %s", username);
-
+
/* start parse content */
while ( parse_state != SMP_ERROR && *ch && continue_search ) {
beg = ch;
while( *ch && *ch != '\n') ch++ ;
-
+
if ( *ch == '\n' ) { *ch = 0; ch++; }
- DEBUG2("parse buffer: <<%s>>\n",beg);
-
+ DEBUG2("parse buffer: <<%s>>\n",beg);
+
retcod = userparse(beg,&vp);
if ( retcod == T_INVALID ) librad_perror("parse error ");
-
+
switch ( retcod ) {
case T_COMMA: break; /* continue parse the current list */
- case T_EOL: DEBUG2("rlm_dbm: recod parsed\n"); /* vp contains full pair list */
+ case T_EOL: DEBUG2("rlm_dbm: recod parsed\n"); /* vp contains full pair list */
if ( parse_state == SMP_PATTERN ) { /* pattern line found */
DEBUG2("process pattern");
/* check pattern against request */
parse_state = SMP_REPLY; /* look for reply */
} else {
/* skip reply */
- DEBUG2("rlm_dbm: patern not matched, reply skiped");
+ DEBUG2("rlm_dbm: patern not matched, reply skiped");
pairfree(&vp);
while ( *ch && *ch !='\n' ) ch++;
if ( *ch == '\n' ) ch++;
/* look for join-attribute */
DEBUG2("rlm_dbm: Reply found");
join_attr = vp;
- while( (join_attr = pairfind(join_attr,SM_JOIN_ATTR) ) != NULL ) {
+ while( (join_attr = pairfind(join_attr,SM_JOIN_ATTR) ) != NULL ) {
DEBUG2("rlm_dbm: Proccess nested record: username %s",
(char *)join_attr->strvalue);
/* res = RLM_MODULE_NOTFOUND; */
- res = sm_parse_user(pdb, (char *)join_attr->strvalue, request, &tmp_config,
+ res = sm_parse_user(pdb, (char *)join_attr->strvalue, request, &tmp_config,
&nu_reply, ulist);
DEBUG("rlm_dbm: recived: %d\n",res);
switch ( res ) {
pairfree(&vp);
pairfree(&nu_reply); }
break;
- default: /* we do not wait that !!!! */
+ default: /* we do not wait that !!!! */
parse_state = SMP_ERROR;
DEBUG2("rlm_dbm: Unknown token: %d\n",retcod);
break;
}
-
+
}
if ( parse_state == SMP_PATTERN ) {
- pairmove(config,&tmp_config);
+ pairmove(config,&tmp_config);
pairfree(&tmp_config);
pairmove(reply,&tmp_reply);
pairfree(&tmp_reply);
static int sm_postprocessor(VALUE_PAIR **reply UNUSED) {
return 0;
-}
+}
static int rlm_dbm_instantiate(CONF_SECTION *conf, void **instance) {
struct rlm_dbm_t *inst;
-
+
inst = rad_malloc(sizeof(rlm_dbm_t));
if (!inst) {
return -1;
memset(inst, 0, sizeof(*inst));
if (cf_section_parse(conf, inst, module_config) < 0) {
- free(inst);
+ free(inst);
return -1;
}
*instance = inst;
int found = 0;
const char *name;
SM_USER_ENTRY *ulist = NULL;
- DBM *pdb;
+ DBM *pdb;
struct rlm_dbm_t *inst = instance;
VALUE_PAIR **check_pairs, **reply_pairs;
-
+
request_pairs = request->packet->vps;
check_pairs = &request->config_items;
reply_pairs = &request->reply->vps;
-
+
/*
* Grab the canonical user name.
*/
namepair = request->username;
name = namepair ? (char *) namepair->strvalue : "NONE";
-
+
DEBUG2("rlm_dbm: try open database file: %s\n",inst -> userfile);
/* open database */
if ( found == RLM_MODULE_NOTFOUND ) {
sm_user_list_wipe(&ulist);
found = sm_parse_user(pdb, "DEFAULT", request_pairs, &check_tmp, &reply_tmp, &ulist);
- }
+ }
dbm_close(pdb);
- } else {
+ } else {
found = RLM_MODULE_FAIL;
DEBUG2("rlm_dbm: Cannot open database file: %s\n",
strerror(errno));
sm_user_list_wipe(&ulist);
pairfree(&reply_tmp);
pairfree(&check_tmp);
-
+
return found;
}
/* globally exported name */
-module_t rlm_dbm = {
+module_t rlm_dbm = {
"dbm",
0, /* type: reserved */
NULL, /* initialization */
int i,j;
char *p;
for(i = 0, p = key.dptr; i < key.dsize; i++, p++)
- putchar(*p);
+ putchar(*p);
if ( i < lotstup ) while( i++ <= lotstup) putchar(' ');
else putchar(' ');
-
+
for(j = 0, p = data.dptr ; j < data.dsize && *p ; i++, p++ ) {
putchar(*p);
if ( needwrap && *p == ',' && i > wraplen ) putchar('\n');
i = 0;
}
}
-
+
putchar('\n');
}
static void usage(void)
{
fprintf(stderr, "Usage: %s: [-f file] [-w] [-i number] [-l number] [-v]\n\n",progname);
-
+
exit(1);
}
datum k,d;
int ch;
int i;
-
+
progname = argv[0];
-
-
-
+
+
+
while ((ch = getopt(n, argv, "i:l:wf:v")) != -1)
switch (ch) {
case 'i': if (!isdigit((int) *optarg)) usage();
case 'l': if (!isdigit((int) *optarg)) usage();
wraplen = atoi(optarg);
break;
- case 'w': needwrap = 1;
+ case 'w': needwrap = 1;
break;
case 'f': fname = optarg;
break;
exit(0);
break;
default : usage(); exit(1); break;
-
+
}
n -= (optind - 1);
argv += (optind -1);
-
+
if ( fname == NULL) fname = "sandy_db";
if ( ( pdb = dbm_open(fname, O_RDONLY, 0777) ) == NULL ) {
for ( i = 1 ; i < n ; i++ ) {
printf(" Check: %s\n",argv[i]);
k.dptr = argv[i];
- k.dsize = strlen(argv[i]) + 1;
+ k.dsize = strlen(argv[i]) + 1;
if ( (d = dbm_fetch(pdb,k)).dptr == NULL ) {
printf("Not found\n");
} else dump_record(k, d);
}
} else {
- for ( k = dbm_firstkey(pdb) ; k.dptr != NULL ; k = dbm_nextkey(pdb) )
+ for ( k = dbm_firstkey(pdb) ; k.dptr != NULL ; k = dbm_nextkey(pdb) )
if ( (d = dbm_fetch(pdb,k)).dptr == NULL ) {
perror("Couldn't fetch user record");
exit(1);
} else dump_record(k, d);
}
dbm_close(pdb);
- fflush(stdout);
-
+ fflush(stdout);
+
return 0;
-
+
}
int dumplist(VALUE_PAIR *vp) {
while (vp != NULL) {
-
+
printf("VP: name: %s\nattribute: %d\ntype: %d\nlvalue: %lu"
"\noperator %d\naddport: %d\nValue: %s\n",
vp -> name, vp -> attribute, vp -> type, vp -> lvalue,
vp -> operator, vp -> addport, (char*)vp -> strvalue);
- vp = vp -> next;
+ vp = vp -> next;
}
return 0;
}
perror("Couldn't open database");
return 1;
}
- return 0;
+ return 0;
}
static void close_storage(void){
- dbm_close(pdb);
+ dbm_close(pdb);
}
static int addlinetocontent(VALUE_PAIR *vp) {
-
+
int outlen = sizeof(content) - concntr - 1;
int lendiv;
-
+
if ( outlen < 4 ) return -1;
if ( vp == NULL ) { /* add empty line */
content[concntr++] = '\n';
lendiv = vp_prints(&content[concntr],outlen,vp);
if ( lendiv > 0 ) {
outlen -= lendiv;
-
+
if (outlen > 3) {
strcat(content,", ");
concntr += lendiv + 2;
} else {
concntr = 0;
return -1;
- }
+ }
}
- vp = vp -> next;
+ vp = vp -> next;
}
-
+
if ( concntr > 2 ) { /* remove trailing ',' */
content[--concntr] = '\0';
content[concntr - 1] = '\n';
}
}
-
- return 0;
+
+ return 0;
}
static int storecontent (const char * username) {
-
+
datum d,k;
int res;
-
+
if ( pdb == NULL || concntr < 3 ) return 1;
DOUT2("store:\n%s\ncontent:\n%s",username,content);
k.dptr = username;
k.dsize = strlen(username) + 1;
-
+
res = dbm_store(pdb, k, d, DBM_INSERT);
if ( res == 1 ) dbm_store(pdb, k, d, DBM_REPLACE);
if ( res < 0 ) {
st_errors++;
st_skiped++;
} else st_loaded++;
-
+
concntr = 0;
*content = '\0';
return 0;
}
static int getuname(char **p,char *u,int n) {
- int i;
-
- for(i=0 ; ( i < n-1 ) && ( **p ) && (! isspace((int) **p) ) ; (*p)++ )
+ int i;
+
+ for(i=0 ; ( i < n-1 ) && ( **p ) && (! isspace((int) **p) ) ; (*p)++ )
u[i++] = **p;
u[i] = '\0';
return ( i == 0) ? 1:0;
static int sm_parse_file(FILE*fp,const char* fname) {
LRAD_TOKEN tok;
VALUE_PAIR *vp = NULL;
- sm_parse_state_t parse_state = SMP_USER;
+ sm_parse_state_t parse_state = SMP_USER;
unsigned long lino = 0;
char *p;
char buff[MAX_BUFF_SIZE];
while( parse_state != SMP_INVALID && fgets(buff, sizeof(buff), fp) != NULL ) {
-
+
lino ++;
st_lines++;
if ( strchr(buff, '\n') == NULL) {
st_skiped++; /* _LINE_ skiped */
continue;
}
-
+
DOUT2("Parseline: %s",buff);
for ( p = buff; isspace((int) *p); p++);
-
+
if ( *p == '#' || *p == 0 ) continue;
/* userparse hack */
if ( parse_state == SMP_USER ) {
tok = getuname(&p,username,sizeof(username));
-
+
/* check: is it include. not implemented */
if ( tok ) {
} else {
parse_state = SMP_PATTERN;
DOUT1("Found user: %s\n",username);
-
+
}
}
if ( parse_state == SMP_PATTERN || parse_state == SMP_ACTION ) {
if ( *p && ( *p != ';' ) ) tok = userparse(p,&vp);
else tok = T_EOL; /* ';' - signs empty line */
-
+
switch(tok) {
case T_EOL: /* add to content */
addlinetocontent(vp);
pairfree(&vp);
- if ( parse_state == SMP_PATTERN )
+ if ( parse_state == SMP_PATTERN )
parse_state = SMP_ACTION;
else parse_state = SMP_PATTERN_OR_USER;
-
+
case T_COMMA: break; /* parse next line */
default: /* error: we do not expect anything else */
- fprintf(stderr ,"%s: %s[%lu]: sintax error\n",progname,fname,lino);
+ fprintf(stderr ,"%s: %s[%lu]: sintax error\n",progname,fname,lino);
librad_perror("Error");
parse_state = SMP_INVALID;
st_errors++;
- }
+ }
}
}
if ( feof(fp) ) switch (parse_state ) {
fprintf(stderr, "-q do not print statistic\n");
fprintf(stderr, "-v print version\n");
fprintf(stderr, "-r remove user(s) from database\n");
-
+
}
int main(int n,char **argv) {
-
+
const char *fname = NULL;
const char *ofile = NULL;
FILE *fp;
int print_stat = 1;
int ch;
const char *sm_radius_dir = NULL;
-
+
progname = argv[0];
librad_debug = 0;
-
- while ((ch = getopt(n, argv, "d:i:xo:qvc")) != -1)
+
+ while ((ch = getopt(n, argv, "d:i:xo:qvc")) != -1)
switch (ch) {
- case 'd':
+ case 'd':
sm_radius_dir = optarg;
break;
case 'i':
librad_debug++;
case 'o':
ofile = optarg;
- break;
+ break;
case 'q':
print_stat = 0;
break;
if ( sm_radius_dir == NULL ) sm_radius_dir = RADDBDIR;
-
+
DOUT1("Use dictionary in: %s\n",sm_radius_dir);
if (dict_init(sm_radius_dir, RADIUS_DICTIONARY) < 0 ) {
librad_perror("parser: init dictionary:");
} else if ( ( fp = fopen(fname, "r") ) == NULL ) {
fprintf( stderr,"%s: Couldn't open source file\n", progname);
exit(1);
- }
-
+ }
+
if ( ofile == NULL ) ofile = "sandy_db" ;
if ( open_storage(ofile) ) {
exit (1);
* we prolly must create it the dir(s)
*/
if ((p) && (stat(buffer, &st) < 0)) {
- *p = '\0';
+ *p = '\0';
/*
* NO previously cached directory name, so we've
* got to create a new one.
* so we've got to create a new one.
*/
if ((inst->last_made_directory == NULL) ||
- (strcmp(inst->last_made_directory, buffer) != 0)) {
-
+ (strcmp(inst->last_made_directory, buffer) != 0)) {
+
/*
* Free any previously cached name.
*/
free((char *) inst->last_made_directory);
inst->last_made_directory = NULL;
}
-
+
/*
* Go create possibly multiple directories.
*/
}
inst->last_made_directory = strdup(buffer);
}
-
- *p = '/';
+
+ *p = '/';
} /* else there was no directory delimiter. */
/*
*/
fseek(outfp, 0L, SEEK_END);
fputs(CTIME_R(&request->timestamp, buffer, DIRLEN), outfp);
-
+
/* Write each attribute/value to the log file */
while (pair) {
/*
else if (request->packet->verified == 1)
fputs("\tRequest-Authenticator = None\n", outfp);
}
-
+
fputs("\n", outfp);
if (inst->locking) {
rad_unlockfd(outfd, 0);
DEBUG("rlm_detail: Released filelock");
}
-
+
fclose(outfp);
/*
}
attrlen = p[1]; /* stupid VSA format */
-
+
/*
* Too short.
*/
DEBUG("ERROR: Received Digest-Attributes with short sub-attribute %d, of length %d", p[0], attrlen);
return RLM_MODULE_INVALID;
}
-
+
/*
* Too long.
*/
*/
length -= attrlen;
- p += attrlen;
+ p += attrlen;
} /* loop over this one attribute */
/*
a2_len += (body->length >> 1);
} else if ((qop != NULL) &&
- (strcasecmp(qop->strvalue, "auth") != 0)) {
+ (strcasecmp(qop->strvalue, "auth") != 0)) {
DEBUG("ERROR: Unknown Digest-QOP \"%s\": Cannot perform Digest authentication", qop->strvalue);
return RLM_MODULE_INVALID;
}
kd[kd_len] = ':';
kd_len++;
-
+
memcpy(&kd[kd_len], nonce->strvalue, nonce->length);
kd_len += nonce->length;
printf("%02x", kd[i]);
}
printf("\n");
-
+
printf("RECEIVED ");
for (i = 0; i < 16; i++) {
printf("%02x", hash[i]);
* is single-threaded.
*/
module_t rlm_digest = {
- "DIGEST",
+ "DIGEST",
0, /* type */
NULL, /* initialization */
NULL, /* instantiation */
* +-+-+-+-+
*
*
- * EAP Request and Response Packet Format
+ * EAP Request and Response Packet Format
* --- ------- --- -------- ------ ------
* 0 1 2 3
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
*
*
- * EAP Success and Failure Packet Format
+ * EAP Success and Failure Packet Format
* --- ------- --- ------- ------ ------
* 0 1 2 3
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
/*
* Load all the required eap authentication types.
- * Get all the supported EAP-types from config file.
+ * Get all the supported EAP-types from config file.
*/
int eaptype_load(EAP_TYPES **type, int eap_type, CONF_SECTION *cs)
{
/* Link the loaded EAP-Type */
handle = lt_dlopenext(buffer);
if (handle == NULL) {
- radlog(L_ERR, "rlm_eap: Failed to link EAP-Type/%s: %s",
+ radlog(L_ERR, "rlm_eap: Failed to link EAP-Type/%s: %s",
eaptype_name, lt_dlerror());
return -1;
}
*/
node->typename = eaptype_name;
node->type_data = NULL;
-
+
node->type = (EAP_TYPE *)lt_dlsym(node->handle, buffer);
if (!node->type) {
radlog(L_ERR, "rlm_eap: Failed linking to %s structure in %s: %s",
free(node);
return -1;
}
- if ((node->type->attach) &&
+ if ((node->type->attach) &&
((node->type->attach)(node->cs, &(node->type_data)) < 0)) {
radlog(L_ERR, "rlm_eap: Failed to initialize type %s",
/*
* Based on TYPE, call the appropriate EAP-type handler
- * Default to the configured EAP-Type
- * for all Unsupported EAP-Types
+ * Default to the configured EAP-Type
+ * for all Unsupported EAP-Types
*/
int eaptype_select(rlm_eap_t *inst, EAP_HANDLER *handler)
{
switch(eaptype->type) {
case PW_EAP_IDENTITY:
DEBUG2(" rlm_eap: EAP Identity");
-
+
/*
* Allow per-user configuration of EAP types.
*/
vp = pairfind(handler->request->config_items,
PW_EAP_TYPE);
if (vp) default_eap_type = vp->lvalue;
-
+
do_initiate:
/*
* Ensure it's valid.
namebuf, sizeof(namebuf)));
return EAP_INVALID;
}
-
+
handler->stage = INITIATE;
handler->eap_type = default_eap_type;
-
+
/*
* Wild & crazy stuff! For TTLS & PEAP, we
* initiate a TLS session, and then pass that
(default_eap_type == PW_EAP_PEAP)) {
default_eap_type = PW_EAP_TLS;
}
-
-
+
+
/*
* We don't do TLS inside of TLS, as it's a bad
* idea...
DEBUG2(" rlm_eap: Unable to tunnel TLS inside of TLS");
return EAP_INVALID;
}
-
+
if (eaptype_call(inst->types[default_eap_type],
handler) == 0) {
- DEBUG2(" rlm_eap: Default EAP type %s failed in initiate",
+ DEBUG2(" rlm_eap: Default EAP type %s failed in initiate",
eaptype_type2name(default_eap_type,
namebuf, sizeof(namebuf)));
return EAP_INVALID;
eaptype_name = eaptype_type2name(default_eap_type,
namebuf, sizeof(namebuf));
DEBUG2(" rlm_eap: EAP-NAK asked for EAP-Type/%s",
- eaptype_name);
+ eaptype_name);
/*
* Prevent a firestorm if the client is confused.
namebuf,
sizeof(namebuf));
DEBUG2(" rlm_eap: EAP/%s", eaptype_name);
-
+
/*
* We haven't configured it, it doesn't exit.
*/
eaptype->type);
return EAP_INVALID;
}
-
+
rad_assert(handler->stage == AUTHENTICATE);
handler->eap_type = eaptype->type;
if (eaptype_call(inst->types[eaptype->type],
* mentioned restriction.
*/
reply->id = handler->eap_ds->response->id;
-
+
switch (reply->code) {
/*
* The Id is a simple "ack" for success
case PW_EAP_SUCCESS:
case PW_EAP_FAILURE:
break;
-
+
/*
* We've sent a response to their
* request, the Id is incremented.
eap_ds->request->type.type = handler->eap_type;
}
-
+
if (eap_wireformat(reply) == EAP_INVALID) {
return RLM_MODULE_INVALID;
eap_len = 0;
}
- /*
+ /*
* create a value pair & append it to the request reply list
* This memory gets freed up when request is freed up
*/
vp->lvalue = eap_msg->strvalue[4];
pairadd(&(request->packet->vps), vp);
}
-
+
/*
* We've been told to ignore unknown EAP
* types, AND it's an unknown type.
return EAP_NOOP;
}
} /* else it's not an EAP-Request or EAP-Response */
-
+
/*
* No EAP-Start found. Proxying: return NOOP.
* Not proxying, return NOTFOUND.
* response = Received EAP packet
* request = Sending EAP packet
*
- * Note: We are authentication server,
- * we get ONLY EAP-Responses and
+ * Note: We are authentication server,
+ * we get ONLY EAP-Responses and
* we send EAP-Request/EAP-success/EAP-failure
*/
typedef struct eap_ds {
/*
* Currently there are only 2 types
- * of operations defined,
+ * of operations defined,
* apart from attach & detach for each EAP-Type.
*/
typedef enum operation_t {
* Each handler contains information for one specific EAP-Type.
* This way we don't need to change any interfaces in future.
* It is also a list of EAP-request handlers waiting for EAP-response
- * eap_id = copy of the eap packet we sent to the
+ * eap_id = copy of the eap packet we sent to the
*
* next = pointer to next
* state = state attribute from the reply we sent
* eap_ds = Current EAP response.
* opaque = EAP-Type holds some data that corresponds to the current
* EAP-request/response
- * free_opaque = To release memory held by opaque,
+ * free_opaque = To release memory held by opaque,
* when this handler is timedout & needs to be deleted.
- * It is the responsibility of the specific EAP-TYPE
+ * It is the responsibility of the specific EAP-TYPE
* to avoid any memory leaks in opaque
* Hence this pointer should be provided by the EAP-Type
* if opaque is not NULL
int stage;
} EAP_HANDLER;
-/*
+/*
* Interface to call EAP sub mdoules
*/
typedef struct eap_type_t {
#define ATTRIBUTE_EAP_SIM_BASE (6*256)
#define ATTRIBUTE_EAP_SIM_SUBTYPE 1023
-#define ATTRIBUTE_EAP_SIM_RAND1 1024
-#define ATTRIBUTE_EAP_SIM_RAND2 1025
-#define ATTRIBUTE_EAP_SIM_RAND3 1026
+#define ATTRIBUTE_EAP_SIM_RAND1 1024
+#define ATTRIBUTE_EAP_SIM_RAND2 1025
+#define ATTRIBUTE_EAP_SIM_RAND3 1026
-#define ATTRIBUTE_EAP_SIM_SRES1 1027
-#define ATTRIBUTE_EAP_SIM_SRES2 1028
-#define ATTRIBUTE_EAP_SIM_SRES3 1029
+#define ATTRIBUTE_EAP_SIM_SRES1 1027
+#define ATTRIBUTE_EAP_SIM_SRES2 1028
+#define ATTRIBUTE_EAP_SIM_SRES3 1029
#define ATTRIBUTE_EAP_SIM_STATE 1030
#define ATTRIBUTE_EAP_SIM_IMSI 1031
enum eapsim_clientstates {
eapsim_client_init = 0,
eapsim_client_start = 1,
- eapsim_client_maxstates
+ eapsim_client_maxstates
};
/* server states
- *
+ *
* in server_start, we send a EAP-SIM Start message.
*
*/
extern int unmap_eapsim_types(RADIUS_PACKET *r);
extern const char *sim_state2name(enum eapsim_clientstates state, char *buf, int buflen);
extern const char *sim_subtype2name(enum eapsim_subtype subtype, char *buf, int buflen);
-extern int unmap_eapsim_basictypes(RADIUS_PACKET *r,
+extern int unmap_eapsim_basictypes(RADIUS_PACKET *r,
uint8_t *attr, unsigned int attrlen);
/************************/
/* CRYPTO FUNCTIONS */
/************************/
-
+
/*
* key derivation functions/structures
*
unsigned char K_encr[16];
unsigned char msk[64];
unsigned char emsk[64];
-};
+};
/*
* +-+-+-+-+
*
*
- * EAP Request and Response Packet Format
+ * EAP Request and Response Packet Format
* --- ------- --- -------- ------ ------
* 0 1 2 3
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
*
*
- * EAP Success and Failure Packet Format
+ * EAP Success and Failure Packet Format
* --- ------- --- ------- ------ ------
* 0 1 2 3
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
static const char rcsid[] = "$Id$";
static const char *eap_types[] = {
- "",
+ "",
"identity",
"notification",
"nak", /* NAK */
return i;
}
}
-
+
return -1;
}
eap_packet_t *hdr;
uint16_t total_length = 0;
-
+
if (reply == NULL) return EAP_INVALID;
-
+
/*
* if reply->packet is set, then the wire format
* has already been calculated, just succeed!
eap_len = 0;
}
- /*
+ /*
* create a value pair & append it to the packet list
* This memory gets freed up when packet is freed up
*/
}
vp = pairfind(req->vps, ATTRIBUTE_EAP_CODE);
- if(vp == NULL) {
+ if(vp == NULL) {
eapcode = PW_EAP_REQUEST;
} else {
eapcode = vp->lvalue;
}
-
+
for(vp = req->vps; vp != NULL; vp = vpnext) {
/* save it in case it changes! */
vpnext = vp->next;
}
eap_type = vp->attribute - ATTRIBUTE_EAP_BASE;
-
+
switch(eap_type) {
case PW_EAP_IDENTITY:
case PW_EAP_NOTIFICATION:
* no known special handling, it is just encoded as an
* EAP-message with the given type.
*/
-
+
/* nuke any existing EAP-Messages */
pairdelete(&req->vps, PW_EAP_MESSAGE);
-
+
memset(&ep, 0, sizeof(ep));
ep.code = eapcode;
ep.id = id;
eap_basic_compose(req, &ep);
}
}
-
+
/*
* Handles multiple EAP-Message attrs
* ie concatenates all to get the complete EAP packet.
total_len = 0;
for (vp = first; vp; vp = pairfind(vp->next, PW_EAP_MESSAGE)) {
total_len += vp->length;
-
+
if (total_len > len) {
radlog(L_ERR, "rlm_eap: Malformed EAP packet. Length in packet header does not match actual length");
return NULL;
case PW_EAP_FAILURE:
/* no data */
break;
-
+
case PW_EAP_REQUEST:
case PW_EAP_RESPONSE:
/* there is a type field, which we use to create
* a new attribute */
-
+
/* the length was decode already into the attribute
* length, and was checked already. Network byte
* order, just pull it out using math.
*/
len = e->length[0]*256 + e->length[1];
-
+
/* verify the length is big enough to hold type */
if(len < 5)
{
}
type = e->data[0];
-
+
type += ATTRIBUTE_EAP_BASE;
len -= 5;
return;
}
-
+
* eapcrypto.c Common key derivation routines for EAP/SIM.
*
* The development of the EAP/SIM support was funded by Internet Foundation
- * Austria (http://www.nic.at/ipa).
+ * Austria (http://www.nic.at/ipa).
*
* Version: $Id$
*
memcpy(p, ek->Kc[2], EAPSIM_Kc_SIZE); p = p+EAPSIM_Kc_SIZE;
memcpy(p, ek->nonce_mt, sizeof(ek->nonce_mt)); p=p+sizeof(ek->nonce_mt);
memcpy(p, ek->versionlist, ek->versionlistlen);p=p+ek->versionlistlen;
- memcpy(p, ek->versionselect, sizeof(ek->versionselect)); p=p+sizeof(ek->versionselect);
+ memcpy(p, ek->versionselect, sizeof(ek->versionselect)); p=p+sizeof(ek->versionselect);
/* *p++ = ek->versionselect[1]; */
-
+
blen = p - buf;
#if defined(TEST_CASE) || defined(DUMP_EAPSIM_KEYS)
{
unsigned int i, j, k;
-
+
j=0; k=0;
-
+
printf("SHA1buffer was: ");
for (i = 0; i < blen; i++) {
if(j==4) {
printf("\n ");
k=0;
j=0;
- }
+ }
j++;
k++;
}
printf("\n");
}
-#endif
+#endif
+
-
/* do the master key first */
SHA1Init(&context);
SHA1Update(&context, buf, blen);
}
printf("\n select %02x %02x\n",
- ek->versionselect[0],
+ ek->versionselect[0],
ek->versionselect[1]);
printf("\n\nOutput\n");
printf("\n ");
k=0;
j=0;
- }
+ }
if(j==4) {
printf("_");
j=0;
printf("\n ");
k=0;
j=0;
- }
+ }
if(j==4) {
printf("_");
j=0;
0x89, 0xab, 0xcd, 0xef, 0x89, 0xab, 0xcd, 0xef,
0x9a, 0xbc, 0xde, 0xf8, 0x9a, 0xbc, 0xde, 0xf8,
0x9a, 0xbc, 0xde, 0xf8, 0x9a, 0xbc, 0xde, 0xf8,
- 0xab, 0xcd, 0xef, 0x89, 0xab, 0xcd, 0xef, 0x89,
+ 0xab, 0xcd, 0xef, 0x89, 0xab, 0xcd, 0xef, 0x89,
0xab, 0xcd, 0xef, 0x89, 0xab, 0xcd, 0xef, 0x89,
0x12, 0x34, 0xab, 0xcd, /* sresX */
- 0x12, 0x34, 0xab, 0xcd,
- 0x23, 0x4a, 0xbc, 0xd1,
+ 0x12, 0x34, 0xab, 0xcd,
+ 0x23, 0x4a, 0xbc, 0xd1,
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, /* Kc */
0x10, 0x21, 0x32, 0x43, 0x54, 0x65, 0x76, 0x87,
0x30, 0x41, 0x52, 0x63, 0x74, 0x85, 0x96, 0xa7,
struct eapsim_keys inputkey2 = {
{'1','2','4','4','0','7','0','1','0','0','0','0','0','0','0','1','@','e','a','p','s','i','m','.','f','o','o'},
- 27,
+ 27,
0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, /* nonce_mt */
0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
0xd1, 0xd2, 0xd3, 0xd4, /* SRES 1 */
- 0xe1, 0xe2, 0xe3, 0xe4,
- 0xf1, 0xf2, 0xf3, 0xf4,
+ 0xe1, 0xe2, 0xe3, 0xe4,
+ 0xf1, 0xf2, 0xf3, 0xf4,
0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, /* Kc */
0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
/* {0x00, 0x02, 0x00, 0x01}, */
- {0x00, 0x01},
+ {0x00, 0x01},
2,
0x00, 0x01 ,
};
}
#endif
-
-
+
+
* eapsimlib.c based upon draft-haverinen-pppext-eap-sim-11.txt.
*
* The development of the EAP/SIM support was funded by Internet Foundation
- * Austria (http://www.nic.at/ipa).
+ * Austria (http://www.nic.at/ipa).
*
* code common to EAP-SIM clients and to servers.
*
* EAP-SIM PACKET FORMAT
* ------- ------ ------
*
- * EAP Request and Response Packet Format
+ * EAP Request and Response Packet Format
* --- ------- --- -------- ------ ------
* 0 1 2 3
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Code | Identifier | Length |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | Type | SIM-Type | SIM-Length | value ... |
+ * | Type | SIM-Type | SIM-Length | value ... |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*
* with SIM-Type/SIM-Length/Value... repeating. SIM-Length is in units
uint8_t *encodedmsg, *attr;
unsigned int id, eapcode;
unsigned char *macspace, *append;
- int appendlen;
+ int appendlen;
macspace = NULL;
append = NULL;
{
continue;
}
-
+
vplen = vp->length;
/*
{
return 0;
}
-
+
/*
* figured out the length, so malloc some space for the results.
* EAP is 1-code, 1-identifier, 2-length, 1-type = 5 overhead.
*
* SIM code adds a subtype, and 2 bytes of reserved = 3.
- *
+ *
*/
/* malloc space for it */
-
+
encoded_size += 3;
encodedmsg = malloc(encoded_size);
if (encodedmsg == NULL) {
eapcode = vp->lvalue;
}
-
+
ep->code = eapcode;
ep->id = (id & 0xff);
ep->type.type = PW_EAP_SIM;
eap_packet_t *hdr;
uint16_t hmaclen, total_length = 0;
unsigned char sha1digest[20];
-
+
total_length = EAP_HEADER_LEN + 1 + encoded_size;
hmaclen = total_length + appendlen;
buffer = (unsigned char *)malloc(hmaclen);
/* done with the buffer, free it */
free(buffer);
-
+
/* now copy the digest to where it belongs in the AT_MAC */
/* note that it is truncated to 128-bits */
memcpy(macspace, sha1digest, 16);
/* if we had an AT_MAC and no key, then fail */
if(macspace != NULL && vp == NULL)
{
- if(encodedmsg != NULL)
+ if(encodedmsg != NULL)
free(encodedmsg);
return 0;
}
-
+
return 1;
}
* wrong and the packet should be discarded.
*
*/
-int unmap_eapsim_basictypes(RADIUS_PACKET *r,
+int unmap_eapsim_basictypes(RADIUS_PACKET *r,
uint8_t *attr, unsigned int attrlen)
{
VALUE_PAIR *newvp;
/*
* calculate the MAC for the EAP message, given the key.
- * The "extra" will be appended to the EAP message and included in the
+ * The "extra" will be appended to the EAP message and included in the
* HMAC.
*
*/
attr += attr[1]*4;
}
}
-
+
/* now, HMAC-SHA1 it with the key. */
lrad_hmac_sha1(buffer, len,
key, 16,
* definitions changed to take a buffer for unknowns
* as this is more thread safe.
*/
-const char *simstates[]={ "init", "start", NULL };
+const char *simstates[]={ "init", "start", NULL };
const char *sim_state2name(enum eapsim_clientstates state,
char *statenamebuf,
const char *subtypes[]={ "subtype0", "subtype1", "subtype2", "subtype3",
"subtype4", "subtype5", "subtype6", "subtype7",
- "subtype8", "subtype9",
+ "subtype8", "subtype9",
"start",
"challenge",
"notification",
"reauth",
- NULL };
+ NULL };
const char *sim_subtype2name(enum eapsim_subtype subtype,
char *subtypenamebuf,
while(!filedone) {
if(req->vps) pairfree(&req->vps);
if(req2->vps) pairfree(&req2->vps);
-
- if ((req->vps = readvp2(stdin, &filedone, "eapsimlib:")) == NULL) {
+
+ if ((req->vps = readvp2(stdin, &filedone, "eapsimlib:")) == NULL) {
break;
}
ATTRIBUTE_EAP_SIM_BASE+PW_EAP_SIM_MAC);
vpkey = pairfind(req->vps, ATTRIBUTE_EAP_SIM_KEY);
vpextra = pairfind(req->vps, ATTRIBUTE_EAP_SIM_EXTRA);
-
+
if(vp != NULL && vpkey != NULL && vpextra!=NULL) {
uint8_t calcmac[16];
j=0;
}
j++;
-
+
printf("%02x", calcmac[i]);
}
printf(" did not match\n");
}
#endif
-
-
+
+
* fips186prf.c An implementation of the FIPS-186-2 SHA1-based PRF.
*
* The development of the EAP/SIM support was funded by Internet Foundation
- * Austria (http://www.nic.at/ipa).
+ * Austria (http://www.nic.at/ipa).
*
* This code was written from scratch by Michael Richardson, and it is
* dual licensed under both GPL and BSD.
int i, carry;
carry = 0;
- for(i=19; i>=0; i--) {
+ for(i=19; i>=0; i--) {
/* for(i=0; i<20; i++) { */
s = a->p[i] + b->p[i] + carry;
sum->p[i] = s & 0xff;
onesixty xval, xkey, w_0, w_1, sum, one;
uint8_t *f;
char zeros[64];
-
+
/*
* let XKEY := MK,
*
- * Step 3: For j = 0 to 3 do
- * a. XVAL = XKEY
- * b. w_0 = SHA1(XVAL)
+ * Step 3: For j = 0 to 3 do
+ * a. XVAL = XKEY
+ * b. w_0 = SHA1(XVAL)
* c. XKEY = (1 + XKEY + w_0) mod 2^160
- * d. XVAL = XKEY
- * e. w_1 = SHA1(XVAL)
+ * d. XVAL = XKEY
+ * e. w_1 = SHA1(XVAL)
* f. XKEY = (1 + XKEY + w_1) mod 2^160
- * 3.3 x_j = w_0|w_1
+ * 3.3 x_j = w_0|w_1
*
*/
memcpy(&xkey, mk, sizeof(xkey));
-
+
/* make the value 1 */
memset(&one, 0, sizeof(one));
one.p[19]=1;
-
+
f=finalkey;
-
+
for(j=0; j<4; j++) {
/* a. XVAL = XKEY */
xval = xkey;
-
+
/* b. w_0 = SHA1(XVAL) */
SHA1Init(&context);
memcpy(zeros, xval.p, 20);
SHA1Transform(context.state, zeros);
SHA1FinalNoLen(w_0.p, &context);
-
+
/* c. XKEY = (1 + XKEY + w_0) mod 2^160 */
onesixty_add_mod(&sum, &xkey, &w_0);
onesixty_add_mod(&xkey, &sum, &one);
-
+
/* d. XVAL = XKEY */
xval = xkey;
-
+
/* e. w_1 = SHA1(XVAL) */
SHA1Init(&context);
memcpy(zeros, xval.p, 20);
SHA1Transform(context.state, zeros);
SHA1FinalNoLen(w_1.p, &context);
-
+
/* f. XKEY = (1 + XKEY + w_1) mod 2^160 */
onesixty_add_mod(&sum, &xkey, &w_1);
onesixty_add_mod(&xkey, &sum, &one);
-
+
/* now store it away */
memcpy(f, &w_0, 20);
f += 20;
-
+
memcpy(f, &w_1, 20);
f += 20;
}
*
* page 5
*
- * XKEY= bd029bbe 7f51960b cf9edb2b 61f06f0f eb5a38b6
- * XSEED= 00000000 00000000 00000000 00000000 00000000
+ * XKEY= bd029bbe 7f51960b cf9edb2b 61f06f0f eb5a38b6
+ * XSEED= 00000000 00000000 00000000 00000000 00000000
+ *
*
+ * The first loop through step 3.2 provides:
+ *
+ * XVAL= bd029bbe 7f51960b cf9edb2b 61f06f0f eb5a38b6
*
- * The first loop through step 3.2 provides:
- *
- * XVAL= bd029bbe 7f51960b cf9edb2b 61f06f0f eb5a38b6
- *
* Using the routine in Appendix 3.3, Constructing The Function G From SHA-1,
* in step 3.2.b of the Change Notice algorithm for computing values of x
- * provides:
- *
- * w[0]= 2070b322 3dba372f de1c0ffc 7b2e3b49 8b260614
- *
- *
- * The following value is the updated XKEY value from step 3.2.c:
- *
- * XKEY= dd734ee0 bd0bcd3b adbaeb27 dd1eaa59 76803ecb
- *
- * The second loop through step 3.2 provides:
- *
- * XVAL= dd734ee0 bd0bcd3b adbaeb27 dd1eaa59 76803ecb
- *
+ * provides:
+ *
+ * w[0]= 2070b322 3dba372f de1c0ffc 7b2e3b49 8b260614
+ *
+ *
+ * The following value is the updated XKEY value from step 3.2.c:
+ *
+ * XKEY= dd734ee0 bd0bcd3b adbaeb27 dd1eaa59 76803ecb
+ *
+ * The second loop through step 3.2 provides:
+ *
+ * XVAL= dd734ee0 bd0bcd3b adbaeb27 dd1eaa59 76803ecb
+ *
* Using the routine in Appendix 3.3, Constructing The Function G From SHA-1,
* in step 3.2.b of the Change Notice algorithm for computing values of x
- * provides:
+ * provides:
+ *
+ * w[1]= 3c6c18ba cb0f6c55 babb1378 8e20d737 a3275116
+ *
+ * The following value is the updated XKEY value from step 3.2.c:
*
- * w[1]= 3c6c18ba cb0f6c55 babb1378 8e20d737 a3275116
*
- * The following value is the updated XKEY value from step 3.2.c:
+ * XKEY= 19df679b 881b3991 6875fea0 6b3f8191 19a78fe2
*
- *
- * XKEY= 19df679b 881b3991 6875fea0 6b3f8191 19a78fe2
+ * Step 3.3 provides the following values:
*
- * Step 3.3 provides the following values:
- *
- * w[0] || w[1]= 2070b322 3dba372f de1c0ffc 7b2e3b49 8b260614
- * 3c6c18ba cb0f6c55 babb1378 8e20d737 a3275116
+ * w[0] || w[1]= 2070b322 3dba372f de1c0ffc 7b2e3b49 8b260614
+ * 3c6c18ba cb0f6c55 babb1378 8e20d737 a3275116
*
*/
printf("%02x", mk[i]);
}
-
+
printf("|\nOutput was: ");
j=0; k=0;
for (i = 0; i < 160; i++) {
printf("\n ");
k=0;
j=0;
- }
+ }
if(j==4) {
printf("_");
j=0;
}
#endif
-
-
+
+
/*
* $Log$
- * Revision 1.2 2003-11-06 15:37:24 aland
+ * Revision 1.3 2004-02-26 19:04:30 aland
+ * perl -i -npe "s/[ \t]+$//g" `find src -name "*.[ch]" -print`
+ *
+ * Whitespace changes only, from a fresh checkout.
+ *
+ * For bug # 13
+ *
+ * Revision 1.2 2003/11/06 15:37:24 aland
* Update includes to work a little better
*
* Revision 1.1 2003/10/29 02:49:19 mcr
EAP_DS *eap_ds_alloc(void)
{
EAP_DS *eap_ds;
-
+
eap_ds = rad_malloc(sizeof(EAP_DS));
memset(eap_ds, 0, sizeof(EAP_DS));
if ((eap_ds->response = eap_packet_alloc()) == NULL) {
EAP_HANDLER *eap_handler_alloc(void)
{
EAP_HANDLER *handler;
-
+
handler = rad_malloc(sizeof(EAP_HANDLER));
memset(handler, 0, sizeof(EAP_HANDLER));
return handler;
eap_handler_free(&node);
node = next;
}
-
+
inst->sessions[i] = NULL;
}
}
*/
state = generate_state(handler->request->timestamp);
pairadd(&(handler->request->reply->vps), state);
-
+
/*
* Create a unique 'key' for the handler, based
* on State, Client-IP-Address, and EAP ID.
last = &(inst->sessions[state->strvalue[0]]);
while (*last) last = &((*last)->next);
-
+
*last = handler;
/*
next = node->next;
/*
- * If the time on this entry has expired,
+ * If the time on this entry has expired,
* delete it. We do this while walking the list,
* in order to spread out the work of deleting old
* sessions.
node = NULL;
break;
}
-
+
DEBUG2(" rlm_eap: Request found, released from the list");
/*
* detach the node from the list
static void usage(void)
{
fprintf(stderr, "Usage: radeapclient [options] server[:port] <command> [<secret>]\n");
-
+
fprintf(stderr, " <command> One of auth, acct, status, or disconnect.\n");
fprintf(stderr, " -c count Send each packet 'count' times.\n");
fprintf(stderr, " -d raddb Set dictionary directory.\n");
fprintf(stderr, "illegal start message has no VERSION_LIST\n");
return 0;
}
-
+
versions = (uint16_t *)vp->strvalue;
/* verify that the attribute length is big enough for a length field */
ntohs(versions[i+1]));
}
}
-
+
/*
* now make sure that we have only FULLAUTH_ID_REQ.
* I think that it actually might not matter - we can answer in
newvp->strvalue[0]=0;
newvp->strvalue[1]=0;
newvp->length = 18; /* 16 bytes of nonce + padding */
-
+
nonce[0]=lrad_rand();
nonce[1]=lrad_rand();
nonce[2]=lrad_rand();
randcfg[0] = &randvp->strvalue[2];
randcfg[1] = &randvp->strvalue[2+EAPSIM_RAND_SIZE];
randcfg[2] = &randvp->strvalue[2+EAPSIM_RAND_SIZE*2];
-
+
randcfgvp[0] = pairfind(rep->vps, ATTRIBUTE_EAP_SIM_RAND1);
randcfgvp[1] = pairfind(rep->vps, ATTRIBUTE_EAP_SIM_RAND2);
randcfgvp[2] = pairfind(rep->vps, ATTRIBUTE_EAP_SIM_RAND3);
j=0;
}
j++;
-
+
fprintf(stderr, "%02x", randcfg[rnum][i]);
}
fprintf(stderr, "\nconfigured rand %d: ", rnum);
j=0;
}
j++;
-
+
fprintf(stderr, "%02x", randcfgvp[rnum]->strvalue[i]);
}
fprintf(stderr, "\n");
Kc1 = pairfind(rep->vps, ATTRIBUTE_EAP_SIM_KC1);
Kc2 = pairfind(rep->vps, ATTRIBUTE_EAP_SIM_KC2);
Kc3 = pairfind(rep->vps, ATTRIBUTE_EAP_SIM_KC3);
-
+
if(Kc1 == NULL ||
Kc2 == NULL ||
Kc3 == NULL) {
j=0;
}
j++;
-
+
printf("%02x", calcmac[i]);
}
printf(" did not match\n");
printf("<+++ EAP-sim decoded packet:\n");
vp_printlist(stdout, req->vps);
-
+
if((vp = pairfind(req->vps, ATTRIBUTE_EAP_SIM_SUBTYPE)) == NULL)
{
return 0;
case eapsim_start:
newstate = process_eap_start(req, resp);
break;
-
+
case eapsim_challenge:
case eapsim_notification:
case eapsim_reauth:
/* NOT SURE ABOUT THIS ONE, retransmit, I guess */
newstate = process_eap_start(req, resp);
break;
-
+
case eapsim_challenge:
newstate = process_eap_challenge(req, resp);
break;
value = &vp->strvalue[1];
name = &vp->strvalue[valuesize+1];
namesize = vp->length - (valuesize + 1);
-
+
/* sanitize items */
if(valuesize > vp->length)
{
return 1;
}
-
+
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));
/*
*password = '\0';
}
- again:
+ 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
*/
switch (vp->attribute) {
default:
break;
-
+
case PW_DIGEST_REALM:
case PW_DIGEST_NONCE:
case PW_DIGEST_METHOD:
break;
}
}
-
+
/*
* If we've already sent a packet, free up the old
* one, and ensure that the next packet has a unique
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;
}
/* 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)
{
goto again;
}
break;
-
+
case ATTRIBUTE_EAP_BASE+PW_EAP_SIM:
if(respond_eap_sim(req, rep))
{
break;
}
}
-
+
return 1;
}
{
switch(c) {
case 'c':
- if (!isdigit((int) *optarg))
+ if (!isdigit((int) *optarg))
usage();
count = atoi(optarg);
break;
case 'r':
- if (!isdigit((int) *optarg))
+ if (!isdigit((int) *optarg))
usage();
retries = atoi(optarg);
break;
case 'i':
- if (!isdigit((int) *optarg))
+ if (!isdigit((int) *optarg))
usage();
id = atoi(optarg);
if ((id < 0) || (id > 255)) {
do_summary = 1;
break;
case 't':
- if (!isdigit((int) *optarg))
+ if (!isdigit((int) *optarg))
usage();
timeout = atof(optarg);
break;
}
#if 0
- {
+ {
FILE *randinit;
if((randinit = fopen("/dev/urandom", "r")) == NULL)
fclose(randinit);
}
}
- lrad_randinit(&randctx, 1);
+ lrad_randinit(&randctx, 1);
#endif
req->id = id;
} else {
fp = stdin;
}
-
+
/*
* Send request.
*/
while(!filedone) {
if(req->vps) pairfree(&req->vps);
-
+
if ((req->vps = readvp2(fp, &filedone, "radeapclient:"))
== NULL) {
break;
}
-
+
sendrecv_eap(req);
}
-
+
if(do_summary) {
printf("\n\t Total approved auths: %d\n", totalapp);
printf("\t Total denied auths: %d\n", totaldeny);
offsetof(rlm_eap_t, timer_limit), NULL, "60"},
{ "ignore_unknown_eap_types", PW_TYPE_BOOLEAN,
offsetof(rlm_eap_t, ignore_unknown_eap_types), NULL, "no" },
-
+
{ NULL, -1, 0, NULL, NULL } /* end the list */
};
int num_types;
CONF_SECTION *scs;
rlm_eap_t *inst;
-
+
inst = (rlm_eap_t *) malloc(sizeof(*inst));
if (!inst) {
return -1;
pthread_mutex_init(&(inst->session_mutex), NULL);
pthread_mutex_init(&(inst->module_mutex), NULL);
#endif
-
+
*instance = inst;
return 0;
}
rlm_eap_t *inst;
int status;
VALUE_PAIR *vp;
-
+
inst = (rlm_eap_t *)instance;
/*
default:
break;
}
-
+
/*
* RFC 2869, Section 2.3.1. If a NAS sends an EAP-Identity,
* it MUST copy the identity into the User-Name attribute.
eap_handler_free(&handler);
return RLM_MODULE_REJECT;
}
-
+
/*
* We are done, wrap the EAP-request in RADIUS to send
* with all other required radius attributes
*/
rcode = eap_compose(handler);
-
+
/*
* Add to the list only if it is EAP-Request, OR if
* it's LEAP, and a response.
/* handler is not required any more, free it now */
eap_handler_free(&handler);
}
-
+
/*
* If it's an Access-Accept, RFC 2869, Section 2.3.1
* says that we MUST include a User-Name attribute in the
pairadd(&(request->reply->vps), vp);
}
}
-
+
return RLM_MODULE_OK;
}
if (!vp) {
return RLM_MODULE_NOOP;
}
-
+
/*
* If it's "leap:session-key", then stop.
*
}
/*
- * Returns 0 on success, non-zero otherwise.
+ * Returns 0 on success, non-zero otherwise.
*/
int verify_state(VALUE_PAIR *state, time_t timestamp)
{
unsigned char hmac[EAP_HMAC_SIZE];
unsigned char value[EAP_CHALLENGE_LEN + sizeof(timestamp)];
-
+
/*
* The length is wrong. Don't do anything.
*/
* to us...
*/
handler->stage = AUTHENTICATE;
-
+
return 1;
}
eap_ds->request->code = PW_EAP_FAILURE;
return 0;
}
-
+
#if 0
if (debug_flag > 2) {
int i;
if ((i & 0x0f) == 0) printf("%d: ", i);
printf("%02x ", eap_ds->response->type.data[i]);
-
+
if ((i & 0x0f) == 0x0f) printf("\n");
}
}
eap_ds->request->code = PW_EAP_FAILURE;
return 0;
}
-
+
if (eap_ds->response->type.length != vp->length) {
DEBUG2(" rlm_eap_gtc: ERROR: Passwords are of different length. %d %d", eap_ds->response->type.length, vp->length);
eap_ds->request->code = PW_EAP_FAILURE;
return 0;
}
-
+
if (memcmp(eap_ds->response->type.data,
vp->strvalue, vp->length) != 0) {
DEBUG2(" rlm_eap_gtc: ERROR: Passwords are different");
eap_ds->request->code = PW_EAP_FAILURE;
return 0;
}
-
+
} else {
radlog(L_ERR, "rlm_eap_gtc: Response is too large to understand");
eap_ds->request->code = PW_EAP_FAILURE;
return 0;
-
+
}
DEBUG2(" rlm_eap_gtc: Everything is OK.");
/*
*
* LEAP Packet Format in EAP Type-Data
- * --- ------ ------ -- --- ---------
+ * --- ------ ------ -- --- ---------
* 0 1 2 3
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*leap_packet_ptr = NULL;
}
-/*
+/*
* Extract the data from the LEAP packet.
- */
+ */
LEAP_PACKET *eapleap_extract(EAP_DS *eap_ds)
{
leap_packet_t *data;
* LEAP can have EAP-Response or EAP-Request (step 5)
* messages sent to it.
*/
- if (!eap_ds ||
- !eap_ds->response ||
+ if (!eap_ds ||
+ !eap_ds->response ||
((eap_ds->response->code != PW_EAP_RESPONSE) &&
(eap_ds->response->code != PW_EAP_REQUEST)) ||
eap_ds->response->type.type != PW_EAP_LEAP ||
*/
unicode[(i << 1)] = password->strvalue[i];
}
-
+
/*
* Get the NT Password hash.
*/
}
-/*
+/*
* Verify the MS-CHAP response from the user.
*/
-int eapleap_stage4(LEAP_PACKET *packet, VALUE_PAIR* password,
+int eapleap_stage4(LEAP_PACKET *packet, VALUE_PAIR* password,
leap_session_t *session)
{
unsigned char ntpwdhash[16];
unsigned char response[24];
-
-
+
+
/*
* No password or previous packet. Die.
*/
return 0;
}
-/*
+/*
* Verify ourselves to the AP
*/
LEAP_PACKET *eapleap_stage6(LEAP_PACKET *packet, REQUEST *request,
- VALUE_PAIR *user_name, VALUE_PAIR* password,
+ VALUE_PAIR *user_name, VALUE_PAIR* password,
leap_session_t *session, VALUE_PAIR **reply_vps)
{
int i;
LEAP_PACKET *reply;
char *p;
VALUE_PAIR *vp;
-
+
/*
* No password or previous packet. Die.
*/
eapleap_free(&reply);
return NULL;
}
-
+
/*
* Copy the name over, and ensure it's NUL terminated.
*/
eapleap_free(&reply);
return NULL;
}
-
+
/*
* Copy the name over, and ensure it's NUL terminated.
*/
return reply;
}
-/*
+/*
* compose the LEAP reply packet in the EAP reply typedata
*/
int eapleap_compose(EAP_DS *eap_ds, LEAP_PACKET *reply)
case PW_EAP_RESPONSE:
eap_ds->request->type.type = PW_EAP_LEAP;
eap_ds->request->type.length = reply->length;
-
+
eap_ds->request->type.data = malloc(reply->length);
if (eap_ds->request->type.data == NULL) {
radlog(L_ERR, "rlm_eap_leap: out of memory");
int eapleap_compose(EAP_DS *auth, LEAP_PACKET *reply);
LEAP_PACKET *eapleap_extract(EAP_DS *auth);
LEAP_PACKET *eapleap_initiate(EAP_DS *eap_ds, VALUE_PAIR *user_name);
-int eapleap_stage4(LEAP_PACKET *packet, VALUE_PAIR* password,
+int eapleap_stage4(LEAP_PACKET *packet, VALUE_PAIR* password,
leap_session_t *session);
LEAP_PACKET *eapleap_stage6(LEAP_PACKET *packet, REQUEST *request,
- VALUE_PAIR *user_name, VALUE_PAIR* password,
+ VALUE_PAIR *user_name, VALUE_PAIR* password,
leap_session_t *session,
VALUE_PAIR **reply_vps);
#endif /*_EAP_LEAP_H*/
/*
* Process the packet. We don't care about any previous
- * EAP packets, as
+ * EAP packets, as
*/
if (!reply) {
return 0;
/*
*
* MD5 Packet Format in EAP Type-Data
- * --- ------ ------ -- --- ---------
+ * --- ------ ------ -- --- ---------
* 0 1 2 3
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*md5_packet_ptr = NULL;
}
-/*
+/*
* We expect only RESPONSE for which SUCCESS or FAILURE is sent back
- */
+ */
MD5_PACKET *eapmd5_extract(EAP_DS *eap_ds)
{
md5_packet_t *data;
* one byte of type data (EAP-MD5) following the 4-byte
* EAP-Packet header.
*/
- if (!eap_ds ||
- !eap_ds->response ||
+ if (!eap_ds ||
+ !eap_ds->response ||
(eap_ds->response->code != PW_MD5_RESPONSE) ||
eap_ds->response->type.type != PW_EAP_MD5 ||
!eap_ds->response->type.data ||
}
-/*
+/*
* verify = MD5(id+password+challenge_sent)
*/
-int eapmd5_verify(MD5_PACKET *packet, VALUE_PAIR* password,
+int eapmd5_verify(MD5_PACKET *packet, VALUE_PAIR* password,
uint8_t *challenge)
{
char *ptr;
return 1;
}
-/*
+/*
* Compose the portions of the reply packet specific to the
* EAP-MD5 protocol, in the EAP reply typedata
*/
* to us...
*/
handler->stage = AUTHENTICATE;
-
+
return 1;
}
length = htons(length);
memcpy(hdr->ms_length, &length, sizeof(uint16_t));
hdr->value_size = MSCHAPV2_CHALLENGE_LEN;
-
+
ptr += MSCHAPV2_HEADER_LEN;
-
+
/*
* Copy the Challenge, success, or error over.
*/
memcpy((eap_ds->request->type.data + 2), &length, sizeof(uint16_t));
memcpy((eap_ds->request->type.data + 4), reply->strvalue + 1, 42);
break;
-
+
case PW_MSCHAP_ERROR:
DEBUG2("MSCHAP Failure\n");
length = 4 + MSCHAPV2_FAILURE_MESSAGE_LEN;
memcpy((eap_ds->request->type.data + 2), &length, sizeof(uint16_t));
memcpy((eap_ds->request->type.data + 4), MSCHAPV2_FAILURE_MESSAGE, MSCHAPV2_FAILURE_MESSAGE_LEN);
break;
-
+
default:
radlog(L_ERR, "rlm_eap_mschapv2: Internal sanity check failed");
return 0;
break;
}
-
+
return 1;
}
handler->opaque = data;
handler->free_opaque = free;
-
+
/*
* Compose the EAP-MSCHAPV2 packet out of the data structure,
* and free it.
* to us...
*/
handler->stage = AUTHENTICATE;
-
+
return 1;
}
/*
* 4 for EAP header, 1 for EAP-MSCHAPv2 code, and
- * 50 for
+ * 50 for
*/
if (eap_ds->response->length < (4 + 1 + MSCHAPV2_RESPONSE_LEN)) {
radlog(L_ERR, "rlm_eap_mschapv2: MS-CHAPV2-Response is too short (%d)", eap_ds->response->length - 5);
/*
- * eap_peap.h
+ * eap_peap.h
*
* Version: $Id$
*
DEBUG2(" rlm_eap_peap: Identity - %s", identity);
return 1;
break;
-
+
/*
* If the first byte of the packet is
* EAP-Response, and the EAP data is a TLV,
if (debug_flag > 2) {
int i;
int total = vp->length - 4;
-
+
if (debug_flag > 0) for (i = 0; i < total; i++) {
if ((i & 0x0f) == 0) printf(" PEAP tunnel data out %04x: ", i);
-
+
printf("%02x ", vp->strvalue[i + 4]);
-
+
if ((i & 0x0f) == 0x0f) printf("\n");
}
if ((total & 0x0f) != 0) printf("\n");
t->status = PEAP_STATUS_SENT_TLV_SUCCESS;
eappeap_success(handler, tls_session);
rcode = RLM_MODULE_HANDLED;
-
+
/*
* If we've been told to use the attributes from
* the reply, then do so.
DEBUG2(" PEAP: Reply was rejected");
eaptls_fail(handler->eap_ds, 0);
return 0;
-
+
case RLM_MODULE_HANDLED:
DEBUG2(" PEAP: Reply was handled");
eaptls_request(handler->eap_ds, tls_session);
case RLM_MODULE_OK:
DEBUG2(" PEAP: Reply was OK");
eaptls_success(handler->eap_ds, 0);
- eaptls_gen_mppe_keys(&handler->request->reply->vps,
+ eaptls_gen_mppe_keys(&handler->request->reply->vps,
tls_session->ssl,
"client EAP encryption");
return 1;
/*
* If there's no data, maybe this is an ACK to an
* MS-CHAP2-Success.
- */
+ */
if (err == 0) {
/*
* FIXME: Call SSL_get_error() to see what went
radlog(L_INFO, "rlm_eap_peap: No data inside of the tunnel.");
return RLM_MODULE_REJECT;
}
-
+
data_len = tls_session->clean_out.used = err;
data = tls_session->clean_out.data;
if (debug_flag > 2) {
for (i = 0; i < data_len; i++) {
if ((i & 0x0f) == 0) printf(" PEAP tunnel data in %04x: ", i);
-
+
printf("%02x ", data[i]);
-
+
if ((i & 0x0f) == 0x0f) printf("\n");
}
if ((data_len & 0x0f) != 0) printf("\n");
if ((data[0] == PW_EAP_IDENTITY) && (data_len > 1)) {
t->username = pairmake("User-Name", "", T_OP_EQ);
rad_assert(t->username != NULL);
-
+
memcpy(t->username->strvalue, data+1, data_len - 1);
t->username->length = data_len -1;
t->username->strvalue[t->username->length] = 0;
#ifndef NDEBUG
if (debug_flag > 0) {
printf(" PEAP: Sending tunneled request\n");
-
+
for (vp = fake->packet->vps; vp != NULL; vp = vp->next) {
putchar('\t');vp_print(stdout, vp);putchar('\n');
}
if (debug_flag > 0) {
printf(" PEAP: Got tunneled reply RADIUS code %d\n",
fake->reply->code);
-
+
for (vp = fake->reply->vps; vp != NULL; vp = vp->next) {
putchar('\t');vp_print(stdout, vp);putchar('\n');
}
*/
if (!t->proxy_tunneled_request_as_eap) {
fake->options |= RAD_REQUEST_OPTION_PROXY_EAP;
-
+
/*
* Hmm... should we check for
* Auth-Type & EAP-Message here?
*/
-
+
/*
* Run the EAP authentication.
*/
rcode = RLM_MODULE_REJECT;
goto done;
}
-
+
/*
* The module decided it wasn't
* done. Handle it like normal.
/*
* Associate the callback with the request.
*/
- rcode = request_data_add(request,
+ rcode = request_data_add(request,
request->proxy,
REQUEST_DATA_EAP_TUNNEL_CALLBACK,
tunnel, free);
rad_assert(rcode == 0);
-
+
/*
* Didn't authenticate the packet, but
* we're proxying it.
fake->reply);
break;
}
-
+
done:
request_free(&fake);
-
+
return rcode;
}
case EAPTLS_SUCCESS:
{
eap_packet_t eap_packet;
-
+
eap_packet.code = PW_EAP_REQUEST;
eap_packet.id = handler->eap_ds->response->id + 1;
eap_packet.length[0] = 0;
record_plus(&tls_session->clean_in,
&eap_packet, sizeof(eap_packet));
-
+
tls_handshake_send(tls_session);
record_init(&tls_session->clean_in);
}
tls_session->opaque = peap_alloc(inst);
tls_session->free_opaque = peap_free;
}
-
+
/*
* Process the PEAP portion of the request.
*/
case RLM_MODULE_REJECT:
eaptls_fail(handler->eap_ds, 0);
return 0;
-
+
case RLM_MODULE_HANDLED:
eaptls_request(handler->eap_ds, tls_session);
return 1;
case RLM_MODULE_OK:
eaptls_success(handler->eap_ds, 0);
- eaptls_gen_mppe_keys(&handler->request->reply->vps,
+ eaptls_gen_mppe_keys(&handler->request->reply->vps,
tls_session->ssl,
"client EAP encryption");
return 1;
* rlm_eap_sim.c Handles that are called from eap for SIM
*
* The development of the EAP/SIM support was funded by Internet Foundation
- * Austria (http://www.nic.at/ipa).
+ * Austria (http://www.nic.at/ipa).
*
* Version: $Id$
*
struct eap_sim_server_state {
enum eapsim_serverstates state;
struct eapsim_keys keys;
-
+
};
/*
* Add value pair to reply
*/
-static void add_reply(VALUE_PAIR** vp,
+static void add_reply(VALUE_PAIR** vp,
const char* name, const char* value, int len)
{
VALUE_PAIR *reply_attr;
reply_attr = pairmake(name, "", T_OP_EQ);
if (!reply_attr) {
DEBUG("rlm_eap_sim: "
- "add_reply failed to create attribute %s: %s\n",
+ "add_reply failed to create attribute %s: %s\n",
name, librad_errstr);
return;
}
struct eap_sim_server_state *ess = (struct eap_sim_server_state *)opaque;
if (!ess) return;
-
+
free(ess);
}
rad_assert(handler->request->reply);
ess = (struct eap_sim_server_state *)handler->opaque;
-
+
/* these are the outgoing attributes */
vps = &handler->request->reply->vps;
ess = (struct eap_sim_server_state *)handler->opaque;
rad_assert(handler->request != NULL);
rad_assert(handler->request->reply);
-
+
/* invps is the data from the client.
* but, this is for non-protocol data here. We should
* already have consumed any client originated data.
printf("+++> EAP-sim decoded packet:\n");
vp_printlist(stdout, *invps);
-
+
/* okay, we got the challenges! Put them into an attribute */
newvp = paircreate(ATTRIBUTE_EAP_SIM_BASE+PW_EAP_SIM_RAND,
PW_TYPE_OCTETS);
/* all set, calculate keys! */
eapsim_calculate_keys(&ess->keys);
-#ifdef EAP_SIM_DEBUG_PRF
+#ifdef EAP_SIM_DEBUG_PRF
eapsim_dump_mk(&ess->keys);
#endif
/*
- * need to include an AT_MAC attribute so that it will get
+ * need to include an AT_MAC attribute so that it will get
* calculated. The NONCE_MT and the MAC are both 16 bytes, so
* we store the NONCE_MT in the MAC for the encoder, which
* will pull it out before it does the operation.
return 1;
}
-#ifndef EAPTLS_MPPE_KEY_LEN
+#ifndef EAPTLS_MPPE_KEY_LEN
#define EAPTLS_MPPE_KEY_LEN 32
#endif
*/
break;
}
-
+
ess->state = newstate;
/* build the target packet */
nonce_vp = pairfind(vps, ATTRIBUTE_EAP_SIM_BASE+PW_EAP_SIM_NONCE_MT);
selectedversion_vp = pairfind(vps, ATTRIBUTE_EAP_SIM_BASE+PW_EAP_SIM_SELECTED_VERSION);
-
+
if(nonce_vp == NULL ||
selectedversion_vp == NULL) {
DEBUG2(" client did not select a version and send a NONCE");
return 0;
}
memcpy(ess->keys.nonce_mt, nonce_vp->strvalue+2, 16);
-
+
/* everything looks good, change states */
eap_sim_stateenter(handler, ess, eapsim_server_challenge);
return 1;
}
-
+
/*
* process an EAP-Sim/Response/Challenge
memcpy(srescat +(0*EAPSIM_SRES_SIZE), ess->keys.sres[0], EAPSIM_SRES_SIZE);
memcpy(srescat +(1*EAPSIM_SRES_SIZE), ess->keys.sres[1], EAPSIM_SRES_SIZE);
memcpy(srescat +(2*EAPSIM_SRES_SIZE), ess->keys.sres[2], EAPSIM_SRES_SIZE);
-
+
/* verify the MAC, now that we have all the keys. */
if(eapsim_checkmac(vps, ess->keys.K_aut,
srescat, sizeof(srescat),
j=0;
}
j++;
-
+
sprintf(m, "%02x", calcmac[i]);
m = m + strlen(m);
}
eap_sim_stateenter(handler, ess, eapsim_server_success);
return 1;
}
-
+
/*
* Authenticate a previously sent challenge.
*/
eap_sim_stateenter(handler, ess, eapsim_server_start);
return 1;
-
+
case eapsim_start:
/*
* a response to our EAP-Sim/Request/Start!
*/
eap_sim_stateenter(handler, ess, eapsim_server_challenge);
return 1;
-
+
case eapsim_challenge:
/*
* a response to our EAP-Sim/Request/Challenge!
/*
* $Log$
- * Revision 1.10 2004-01-30 20:35:33 mcr
+ * Revision 1.11 2004-02-26 19:04:31 aland
+ * perl -i -npe "s/[ \t]+$//g" `find src -name "*.[ch]" -print`
+ *
+ * Whitespace changes only, from a fresh checkout.
+ *
+ * For bug # 13
+ *
+ * Revision 1.10 2004/01/30 20:35:33 mcr
* capture the RAND/SRES/Kc when we initialize the SIM
* rather than later, when they may have changed.
*
/*
- * cb.c
+ * cb.c
*
* Version: $Id$
*
* 4.Verifying that the credentials presented by the certificate
* fulfill additional requirements specific to the application,
* such as with respect to access control lists or with respect
- * to OCSP (Online Certificate Status Processing).
+ * to OCSP (Online Certificate Status Processing).
*
* NOTE: This callback will be called multiple times based on the
* depth of the root certificate chain
{
char subject[256]; /* Used for the subject name */
char issuer[256]; /* Used for the issuer name */
- char buf[256];
+ char buf[256];
char *user_name = NULL; /* User-Name */
X509 *client_cert;
SSL *ssl;
}
*/
radlog(L_INFO, "error=%d", err);
-
+
radlog(L_INFO, "--> User-Name = %s", user_name);
radlog(L_INFO, "--> BUF-Name = %s", buf);
radlog(L_INFO, "--> subject = %s", subject);
* Fill in our 'info' with TLS data.
*/
void cbtls_msg(int write_p, int msg_version, int content_type,
- const void *buf, size_t len,
+ const void *buf, size_t len,
SSL *ssl UNUSED, void *arg)
{
tls_session_t *state = (tls_session_t *)arg;
state->info.alert_level = ((const unsigned char*)buf)[0];
state->info.alert_description = ((const unsigned char*)buf)[1];
state->info.handshake_type = 0x00;
-
+
} else if (content_type == SSL3_RT_HANDSHAKE) {
state->info.handshake_type = ((const unsigned char*)buf)[0];
state->info.alert_level = 0x00;
tls_session_information(state);
}
-int cbtls_password(char *buf,
- int num UNUSED,
- int rwflag UNUSED,
+int cbtls_password(char *buf,
+ int num UNUSED,
+ int rwflag UNUSED,
void *userdata)
{
strcpy(buf, (char *)userdata);
/*
*
- * TLS Packet Format in EAP
+ * TLS Packet Format in EAP
* --- ------ ------ -- ---
* 0 1 2 3
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
/*
A single TLS record may be up to 16384 octets in length, but a TLS
message may span multiple TLS records, and a TLS certificate message
- may in principle be as long as 16MB.
+ may in principle be as long as 16MB.
*/
/*
unsigned int nlen;
unsigned int lbit = 0;
- /* This value determines whether we set (L)ength flag for
- EVERY packet we send and add corresponding
+ /* This value determines whether we set (L)ength flag for
+ EVERY packet we send and add corresponding
"TLS Message Length" field.
length_flag = TRUE;
This means we include L flag and "TLS Msg Len" in EVERY
packet we send out.
-
+
length_flag = FALSE;
This means we include L flag and "TLS Msg Len" **ONLY**
- in First packet of a fragment series. We do not use
+ in First packet of a fragment series. We do not use
it anywhere else.
Having L flag in every packet is prefered.
* Find if this is a reply to the previous request sent
*/
if ((eaptls_packet == NULL) ||
- ((eap_ds->response->length == EAP_HEADER_LEN + 2) &&
+ ((eap_ds->response->length == EAP_HEADER_LEN + 2) &&
((eaptls_packet->flags & 0xc0) == 0x00))) {
-
+
if (prev_eap_ds->request->id == eap_ds->response->id) {
/*
* Run the ACK handler directly from here.
tls_session = (tls_session_t *)handler->opaque;
- if ((status == EAPTLS_MORE_FRAGMENTS) ||
- (status == EAPTLS_MORE_FRAGMENTS_WITH_LENGTH) ||
+ if ((status == EAPTLS_MORE_FRAGMENTS) ||
+ (status == EAPTLS_MORE_FRAGMENTS_WITH_LENGTH) ||
(status == EAPTLS_FIRST_FRAGMENT)) {
/*
* Send the ACK.
DEBUG2(" rlm_eap_tls: processing TLS");
- /* This case is when SSL generates Alert then we
+ /* This case is when SSL generates Alert then we
* send that alert to the client and then send the EAP-Failure
*/
status = eaptls_verify(handler);
return EAPTLS_FAIL;
/*
- * Get the session struct from the handler
+ * Get the session struct from the handler
*
* update the dirty_in buffer
*
* CAUTION while reinitializing this buffer, it should be
* reinitialized only when this M bit is NOT set.
*/
- if (tlspacket->dlen !=
+ if (tlspacket->dlen !=
record_plus(&tls_session->dirty_in, tlspacket->data, tlspacket->dlen)) {
eaptls_free(&tlspacket);
radlog(L_ERR, "rlm_eap_tls: Exceeded maximum record size");
* Continue the handshake.
*/
eaptls_operation(tlspacket, status, handler);
-
+
eaptls_free(&tlspacket);
return EAPTLS_HANDLED;
}
/*
- * eap_tls.h
+ * eap_tls.h
*
* Version: $Id$
*
* use the OpenSSL names for these.
*/
enum ContentType {
- change_cipher_spec = 20,
- alert = 21,
+ change_cipher_spec = 20,
+ alert = 21,
handshake = 22,
application_data = 23
};
/*
* From rfc
Flags
-
+
0 1 2 3 4 5 6 7 8
+-+-+-+-+-+-+-+-+
|L M S R R R R R|
+-+-+-+-+-+-+-+-+
-
+
L = Length included
M = More fragments
S = EAP-TLS start
R = Reserved
-
+
The L bit (length included) is set to indicate the presence of the
four octet TLS Message Length field, and MUST be set for the first
fragment of a fragmented TLS message or set of messages. The M bit
(EAP-TLS start) is set in an EAP-TLS Start message. This
differentiates the EAP-TLS Start message from a fragment
acknowledgement.
-
+
TLS Message Length
-
+
The TLS Message Length field is four octets, and is present only
if the L bit is set. This field provides the total length of the
TLS message or set of messages that is being fragmented.
-
+
TLS data
-
+
The TLS data consists of the encapsulated TLS packet in TLS record
format.
*
/* record */
void record_init(record_t *buf);
void record_close(record_t *buf);
-unsigned int record_plus(record_t *buf, const unsigned char *ptr,
+unsigned int record_plus(record_t *buf, const unsigned char *ptr,
unsigned int size);
-unsigned int record_minus(record_t *buf, unsigned char *ptr,
+unsigned int record_minus(record_t *buf, unsigned char *ptr,
unsigned int size);
#endif /*_EAP_TLS_H*/
/*
* Add value pair to reply
*/
-static void add_reply(VALUE_PAIR** vp,
+static void add_reply(VALUE_PAIR** vp,
const char* name, const char* value, int len)
{
VALUE_PAIR *reply_attr;
reply_attr = pairmake(name, "", T_OP_EQ);
if (!reply_attr) {
DEBUG("rlm_eap_tls: "
- "add_reply failed to create attribute %s: %s\n",
+ "add_reply failed to create attribute %s: %s\n",
name, librad_errstr);
return;
}
/*
* TLS PRF from RFC 2246
*/
-static void P_hash(const EVP_MD *evp_md,
+static void P_hash(const EVP_MD *evp_md,
const unsigned char *secret, unsigned int secret_len,
const unsigned char *seed, unsigned int seed_len,
unsigned char *out, unsigned int out_len)
PRF(s->session->master_key, s->session->master_key_length,
seed, prf_size, out, buf, sizeof(out));
-
+
p = out;
add_reply(reply_vps, "MS-MPPE-Recv-Key", p, EAPTLS_MPPE_KEY_LEN);
p += EAPTLS_MPPE_KEY_LEN;
}
SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(conf->ca_file));
- /*
+ /*
* Set the password to load private key
*/
if (conf->private_key_password) {
ctx_options |= SSL_OP_NO_SSLv2;
ctx_options |= SSL_OP_NO_SSLv3;
- /*
+ /*
* SSL_OP_SINGLE_DH_USE must be used in order to prevent
* small subgroup attacks and forward secrecy. Always
* using
conf->private_key_password = NULL;
if (conf->random_file) free(conf->random_file);
conf->random_file = NULL;
-
+
free(inst->conf);
inst->conf = NULL;
}
int i;
unsigned int data_len;
unsigned char buffer[1024];
-
+
data_len = record_minus(&tls_session->dirty_in,
buffer, sizeof(buffer));
log_debug(" Tunneled data (%u bytes)\n", data_len);
for (i = 0; i < data_len; i++) {
if ((i & 0x0f) == 0) printf(" %d: ", i);
if ((i & 0x0f) == 0x0f) printf("\n");
-
+
printf("%02x ", buffer[i]);
}
}
* Success: Return MPPE keys.
*/
eaptls_success(handler->eap_ds, 0);
- eaptls_gen_mppe_keys(&handler->request->reply->vps,
+ eaptls_gen_mppe_keys(&handler->request->reply->vps,
tls_session->ssl,
"client EAP encryption");
return 1;
/*
- * rlm_eap_tls.h
+ * rlm_eap_tls.h
*
* Version: $Id$
*
*/
typedef struct _record_t {
unsigned char data[MAX_RECORD_SIZE];
- unsigned int used;
+ unsigned int used;
} record_t;
typedef struct _tls_info_t {
/*
* tls_session_t Structure gets stored as opaque in EAP_HANDLER
- * This contains EAP-REQUEST specific data
+ * This contains EAP-REQUEST specific data
* (ie EAPTLS_DATA(fragment), EAPTLS-ALERT, EAPTLS-REQUEST ...)
*
* clean_in - data that needs to be sent but only after it is soiled.
* dirty_in - data EAP server receives.
* clean_out - data that is cleaned after receiving.
- * dirty_out - data EAP server sends.
+ * dirty_out - data EAP server sends.
* offset - current fragment size transmitted
* fragment - Flag, In fragment mode or not.
* tls_msg_len - Actual/Total TLS message length.
record_t dirty_out;
/*
- * Framed-MTU attribute in RADIUS,
+ * Framed-MTU attribute in RADIUS,
* if present, can also be used to set this
*/
unsigned int offset;
/*
- * tls.c
+ * tls.c
*
* Version: $Id$
*
* We are the server, we always get the dirty data
* (Handshake data is also considered as dirty data)
* During handshake, since SSL API handles itself,
- * After clean-up, dirty_out will be filled with
+ * After clean-up, dirty_out will be filled with
* the data required for handshaking. So we check
* if dirty_out is empty then we simply send it back.
* As of now, if handshake is successful, then it is EAP-Success
* or else EAP-failure should be sent
*
- * Fill the Bio with the dirty data to clean it
+ * Fill the Bio with the dirty data to clean it
* Get the cleaned data from SSL, if it is not Handshake data
*/
int tls_handshake_recv(tls_session_t *ssn)
if(ssn->ssl)
SSL_free(ssn->ssl);
#if 0
-/*
+/*
* WARNING: SSL_free seems to decrement the reference counts already,
* so doing this might crash the application.
*/
if (debug_flag == 0) {
return;
}
-
+
str_write_p = tls_session->info.origin ? ">>>" : "<<<";
switch (tls_session->info.version)
if (tls_session->info.content_type == SSL3_RT_ALERT) {
str_details1 = ", ???";
-
+
if (tls_session->info.record_len == 2) {
switch (tls_session->info.alert_level) {
}
}
}
-
+
if (tls_session->info.content_type == SSL3_RT_HANDSHAKE) {
str_details1 = "???";
}
}
- sprintf(tls_session->info.info_description, "%s %s%s [length %04lx]%s%s\n",
- str_write_p, str_version, str_content_type,
+ sprintf(tls_session->info.info_description, "%s %s%s [length %04lx]%s%s\n",
+ str_write_p, str_version, str_content_type,
(unsigned long)tls_session->info.record_len, str_details1, str_details2);
DEBUG2(" rlm_eap_tls: %s\n", tls_session->info.info_description);
}
/*
- * eap_ttls.h
+ * eap_ttls.h
*
* Version: $Id$
*
*/
case PW_AUTHENTICATION_ACK:
eaptls_success(handler->eap_ds, 0);
- eaptls_gen_mppe_keys(&handler->request->reply->vps,
+ eaptls_gen_mppe_keys(&handler->request->reply->vps,
tls_session->ssl,
"ttls keying material");
return 1;
#include "eap_ttls.h"
/*
- * 0 1 2 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | AVP Code |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * |V M r r r r r r| AVP Length |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | Vendor-ID (opt) |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | Data ...
- * +-+-+-+-+-+-+-+-+
+ * 0 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | AVP Code |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |V M r r r r r r| AVP Length |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Vendor-ID (opt) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Data ...
+ * +-+-+-+-+-+-+-+-+
*/
/*
attribute = (vendor << 16) | attr;
da = dict_attrbyvalue(attribute);
-
+
/*
* SHOULD check ((length & (1 << 30)) != 0)
* for the mandatory bit.
/*
* Too short or too long is bad.
*
- * FIXME: EAP-Message
+ * FIXME: EAP-Message
*/
if ((length < offset) ||
(length > (MAX_STRING_LEN + 8)) ||
pairfree(&first);
return NULL;
}
-
+
/*
* If it's a type from our dictionary, then
* we need to put the data in a relevant place.
return NULL;
}
memcpy(&vp->lvalue, data, vp->length);
-
+
/*
* Stored in network byte order: don't change it.
*/
case PW_USER_PASSWORD:
{
int i;
-
+
for (i = 0; i < vp->length; i++) {
if (vp->strvalue[i] == 0) {
vp->length = i;
if (total > 0) {
#ifndef NDEBUG
int i;
-
+
if (debug_flag > 2) {
for (i = 0; i < total; i++) {
if ((i & 0x0f) == 0) printf(" TTLS tunnel data out %04x: ", i);
-
+
printf("%02x ", buffer[i]);
-
+
if ((i & 0x0f) == 0x0f) printf("\n");
}
if ((total & 0x0f) != 0) printf("\n");
case RLM_MODULE_REJECT:
DEBUG2(" TTLS: Reply was rejected");
return 0;
-
+
case RLM_MODULE_HANDLED:
DEBUG2(" TTLS: Reply was handled");
eaptls_request(handler->eap_ds, tls_session);
case RLM_MODULE_OK:
DEBUG2(" TTLS: Reply was OK");
eaptls_success(handler->eap_ds, 0);
- eaptls_gen_mppe_keys(&handler->request->reply->vps,
+ eaptls_gen_mppe_keys(&handler->request->reply->vps,
tls_session->ssl,
"ttls keying material");
return 1;
/*
* If there's no data, maybe this is an ACK to an
* MS-CHAP2-Success.
- */
+ */
if (err == 0) {
if (t->authenticated) {
DEBUG2(" TTLS: Got ACK, and the user was already authenticated.");
if (debug_flag > 2) {
for (i = 0; i < data_len; i++) {
if ((i & 0x0f) == 0) printf(" TTLS tunnel data in %04x: ", i);
-
+
printf("%02x ", data[i]);
-
+
if ((i & 0x0f) == 0x0f) printf("\n");
}
if ((data_len & 0x0f) != 0) printf("\n");
*/
t->username = pairmake("User-Name", "", T_OP_EQ);
rad_assert(t->username != NULL);
-
+
memcpy(t->username->strvalue, vp->strvalue + 5,
vp->length - 5);
t->username->length = vp->length - 5;
t->username->strvalue[t->username->length] = 0;
-
+
DEBUG2(" TTLS: Got tunneled identity of %s",
t->username->strvalue);
}
}
#endif
-
+
/*
* Decide what to do with the reply.
*/
/*
* Associate the callback with the request.
*/
- rcode = request_data_add(request,
+ rcode = request_data_add(request,
request->proxy,
REQUEST_DATA_EAP_TUNNEL_CALLBACK,
tunnel, free);
rad_assert(rcode == 0);
-
+
/*
* Didn't authenticate the packet, but
* we're proxying it.
fake->reply);
break;
}
-
+
request_free(&fake);
return rcode;
/*
- * other.c
+ * other.c
*
* Version: $Id$
*
/*
- * rlm_example.c
+ * rlm_example.c
*
* Version: $Id$
*
static int example_instantiate(CONF_SECTION *conf, void **instance)
{
rlm_example_t *data;
-
+
/*
* Set up a storage area for instance data
*/
free(data);
return -1;
}
-
+
*instance = data;
-
+
return 0;
}
/* quiet the compiler */
instance = instance;
request = request;
-
+
return RLM_MODULE_OK;
}
/* quiet the compiler */
instance = instance;
request = request;
-
+
return RLM_MODULE_OK;
}
/* quiet the compiler */
instance = instance;
request = request;
-
+
return RLM_MODULE_OK;
}
* is single-threaded.
*/
module_t rlm_example = {
- "example",
+ "example",
RLM_TYPE_THREAD_SAFE, /* type */
example_init, /* initialization */
example_instantiate, /* instantiation */
/*
* Do xlat of strings.
- */
+ */
static int exec_xlat(void *instance, REQUEST *request,
char *fmt, char *out, int outlen,
RADIUS_ESCAPE_STRING func)
{
rlm_exec_t *inst;
char *xlat_name;
-
+
/*
* Set up a storage area for instance data
*/
-
+
inst = rad_malloc(sizeof(rlm_exec_t));
if (!inst)
return -1;
memset(inst, 0, sizeof(rlm_exec_t));
-
+
/*
* If the configuration parameters can't be parsed, then
* fail.
exec_detach(inst);
return -1;
}
-
+
/*
* No input pairs defined. Why are we executing a program?
*/
inst->packet_code = 0;
} else {
DICT_VALUE *dval;
-
+
dval = dict_valbyname(PW_PACKET_TYPE, inst->packet_type);
if (!dval) {
radlog(L_ERR, "rlm_exec: Unknown packet type %s: See list of VALUEs for Packet-Type in share/dictionary", inst->packet_type);
}
xlat_name = cf_section_name2(conf);
- if (xlat_name == NULL)
+ if (xlat_name == NULL)
xlat_name = cf_section_name1(conf);
- if (xlat_name){
+ if (xlat_name){
inst->xlat_name = strdup(xlat_name);
- xlat_register(xlat_name, exec_xlat, inst);
- }
+ xlat_register(xlat_name, exec_xlat, inst);
+ }
*instance = inst;
-
+
return 0;
}
expr_token_t token;
} expr_map_t;
-static expr_map_t map[] =
+static expr_map_t map[] =
{
{'+', TOKEN_ADD },
{'-', TOKEN_SUBTRACT },
DEBUG2("rlm_expr: Not a number at \"%s\"", p);
return -1;
}
-
+
/*
* This is doing it the hard way, but it also allows
* us to increment 'p'.
case TOKEN_NONE:
result = x;
break;
-
+
case TOKEN_ADD:
result += x;
break;
/*
* Do xlat of strings!
- */
+ */
static int expr_xlat(void *instance, REQUEST *request, char *fmt, char *out, int outlen,
RADIUS_ESCAPE_STRING func)
{
{
rlm_expr_t *inst;
char *xlat_name;
-
+
/*
* Set up a storage area for instance data
*/
-
+
inst = rad_malloc(sizeof(rlm_expr_t));
if (!inst)
return -1;
memset(inst, 0, sizeof(rlm_expr_t));
-
+
xlat_name = cf_section_name2(conf);
- if (xlat_name == NULL)
+ if (xlat_name == NULL)
xlat_name = cf_section_name1(conf);
- if (xlat_name){
+ if (xlat_name){
inst->xlat_name = strdup(xlat_name);
- xlat_register(xlat_name, expr_xlat, inst);
- }
+ xlat_register(xlat_name, expr_xlat, inst);
+ }
*instance = inst;
-
+
return 0;
}
/* Function declarations */
static int fallthrough(VALUE_PAIR *vp);
static int fastuser_buildhash(struct fastuser_instance *inst);
-static int fastuser_getfile(struct fastuser_instance *inst, const char *filename,
- PAIR_LIST **default_list, PAIR_LIST **pair_list,
+static int fastuser_getfile(struct fastuser_instance *inst, const char *filename,
+ PAIR_LIST **default_list, PAIR_LIST **pair_list,
int isacctfile);
static int fastuser_hash(const char *s, long hashtablesize);
static int fastuser_store(PAIR_LIST **hashtable, PAIR_LIST *entry, int idx);
{
VALUE_PAIR *authtype;
- /*
+ /*
* We check for Auth-Type = Reject here
*/
int reloadusers = 1;
int reloadacctusers = 1;
- /*
+ /*
* Allocate space for hash table here
*/
memsize = sizeof(PAIR_LIST *) * inst->hashsize;
cur = oldhash[hashindex];
pairlist_free(&cur);
}
- }
+ }
free(oldhash);
}
pairlist_free(&olddefaults);
pairlist_free(&oldacctusers);
}
- if(inst->stats)
+ if(inst->stats)
fastuser_tablestats(inst->hashtable, inst->hashsize);
- return 0;
+ return 0;
}
-static int fastuser_getfile(struct fastuser_instance *inst, const char *filename,
- PAIR_LIST **default_list, PAIR_LIST **pair_list,
+static int fastuser_getfile(struct fastuser_instance *inst, const char *filename,
+ PAIR_LIST **default_list, PAIR_LIST **pair_list,
int isacctfile) {
int rcode;
PAIR_LIST *users = NULL;
if (strcmp(inst->compat_mode, "cistron") == 0) {
compat_mode = TRUE;
}
-
+
entry = users;
while (entry) {
if (compat_mode) {
* Ignore attributes which are set
* properly.
*/
- if (vp->operator != T_OP_EQ)
+ if (vp->operator != T_OP_EQ)
continue;
-
+
/*
* If it's a vendor attribute,
- * or it's a wire protocol,
+ * or it's a wire protocol,
* ensure it has '=='.
*/
if (((vp->attribute & ~0xffff) != 0) ||
vp->operator = T_OP_CMP_EQ;
continue;
}
-
+
/*
* Cistron Compatibility mode.
*
vp->operator = T_OP_CMP_EQ;
}
}
-
+
} /* end of loop over check items */
-
-
+
+
/*
* Look for server configuration items
* in the reply list.
log_debug("[%s]:%d WARNING! Check item \"%s\"\n"
"\tfound in reply item list for user \"%s\".\n"
"\tThis attribute MUST go on the first line"
- " with the other check items",
+ " with the other check items",
filename, entry->lineno, vp->name,
entry->name);
}
if(!isacctfile) {
/* Save the DEFAULT entry specially */
if(strcmp(entry->name, "DEFAULT")==0) {
-
+
/* Save this as the last default we've seen */
lastdefault = entry;
numdefaults++;
-
+
/* put it at the end of the list */
if(defaults) {
for(cur=defaults; cur->next; cur=cur->next);
entry->next = NULL;
} else {
defaults = entry;
- defaults->next = NULL;
+ defaults->next = NULL;
}
-
+
} else {
numusers++;
-
+
/* Hash the username */
hashindex = fastuser_hash(entry->name, inst->hashsize);
-
+
/* Store the last default before this entry */
entry->lastdefault = lastdefault;
-
+
/* Store user in the hash */
fastuser_store(pair_list, entry, hashindex);
}
cur = hashtable[idx];
/* store new record at end of list */
if(cur) {
- while (cur->next != NULL)
+ while (cur->next != NULL)
cur=cur->next;
cur->next = new;
new->next = NULL;
* Looks up user in hashtable. If user can't be found, returns 0.
* Otherwise returns a pointer to the structure for the user
*/
-static PAIR_LIST *fastuser_find(REQUEST *request, PAIR_LIST *user,
+static PAIR_LIST *fastuser_find(REQUEST *request, PAIR_LIST *user,
const char *username)
{
PAIR_LIST *cur=user;
if(mainconfig.do_usercollide) {
if((userfound = fastuser_passcheck(request, cur, username))==0) {
cur = cur->next;
- }
+ }
} else {
userfound = 1;
}
}
- for(i=0; i<256; i++)
+ for(i=0; i<256; i++)
if(countarray[i]) {
radlog(L_INFO, "rlm_fastusers: Hash buckets with %d users: %d",
i, countarray[i]);
}
if(toomany) {
- radlog(L_INFO, "rlm_fastusers: Hash buckets with more than 256: %d",
+ radlog(L_INFO, "rlm_fastusers: Hash buckets with more than 256: %d",
toomany);
}
}
int found=0;
VALUE_PAIR *check_save;
- /*
+ /*
* We check for REJECT specially here or a REJECT
* user will never match
*/
check_save = pairfind(user->check, PW_AUTHTYPE);
if((check_save) && check_save->lvalue == PW_AUTHTYPE_REJECT) {
- DEBUG2(" fastusers(uc): User '%s' line %d is Auth-Type Reject, but usercollide match",
+ DEBUG2(" fastusers(uc): User '%s' line %d is Auth-Type Reject, but usercollide match",
user->name, user->lineno);
return 1;
}
/* Save the orginal config items */
check_save = request->config_items;
request->config_items = NULL;
-
+
DEBUG2(" fastusers(uc): Checking %s at %d", user->name, user->lineno);
/* Copy this users check pairs to the request */
}
/* Restore check items */
- pairfree(&request->config_items);
+ pairfree(&request->config_items);
request->config_items = check_save;
return found;
hashidx = fastuser_hash(name, inst->hashsize);
user = inst->hashtable[hashidx];
if((user=fastuser_find(request, user, name))!=NULL) {
- userfound = 1;
+ userfound = 1;
}
- /*
+ /*
* If there's no lastdefault and we
* don't fallthrough, just copy the
* pairs for this user and return
check_tmp = paircopy(user->check);
pairmove(&request->config_items, &check_tmp);
- pairfree(&check_tmp);
+ pairfree(&check_tmp);
reply_tmp = paircopy(user->reply);
pairmove(&request->reply->vps, &reply_tmp);
}
}
- /*
- * When we get here, we've either found
+ /*
+ * When we get here, we've either found
* the user or not, but to preserve order
* we start at the top of the default
* list and work our way thru
* and return
*/
DEBUG2("rlm_fastusers: checking defaults");
-
+
curdefault = inst->defaults;
while(curdefault) {
- if(paircmp(request, request->packet->vps, curdefault->check,
+ if(paircmp(request, request->packet->vps, curdefault->check,
&request->reply->vps) == 0) {
- DEBUG2(" fastusers: Matched %s at %d",
+ DEBUG2(" fastusers: Matched %s at %d",
curdefault->name, curdefault->lineno);
defaultfound = 1;
check_tmp = paircopy(curdefault->check);
pairmove(&request->config_items, &check_tmp);
- pairfree(&check_tmp);
+ pairfree(&check_tmp);
reply_tmp = paircopy(curdefault->reply);
pairmove(&request->reply->vps, &reply_tmp);
pairfree(&reply_tmp);
- /*
- * There's no fallthru on this default which
- * is *before* we find the user in the file,
- * so we know it's safe to quit here
+ /*
+ * There's no fallthru on this default which
+ * is *before* we find the user in the file,
+ * so we know it's safe to quit here
*/
if (!fallthrough(curdefault->reply))
break;
check_tmp = paircopy(user->check);
pairmove(&request->config_items, &check_tmp);
- pairfree(&check_tmp);
+ pairfree(&check_tmp);
reply_tmp = paircopy(user->reply);
pairmove(&request->reply->vps, &reply_tmp);
return(rad_check_return(user->check));
}
- /*
+ /*
* Find next occurence of THIS user in
* the users file
*/
user=user->next;
user=fastuser_find(request, user, name);
- }
+ }
curdefault = curdefault->next;
}
name = namepair ? (char *) namepair->strvalue : "NONE";
request_pairs = request->packet->vps;
config_pairs = &request->config_items;
-
+
/*
* Find the entry for the user.
*/
cur = inst->hashtable[hashindex];
pairlist_free(&cur);
}
- }
+ }
free(inst->compat_mode);
free(inst->hashtable);
if (strcmp(compat_mode_str, "cistron") == 0) {
compat_mode = TRUE;
}
-
+
entry = users;
while (entry) {
if (compat_mode) {
/*
* If it's a vendor attribute,
- * or it's a wire protocol,
+ * or it's a wire protocol,
* ensure it has '=='.
*/
if (((vp->attribute & ~0xffff) != 0) ||
vp->operator = T_OP_CMP_EQ;
continue;
}
-
+
/*
* Cistron Compatibility mode.
*
vp->operator = T_OP_CMP_EQ;
}
}
-
+
} /* end of loop over check items */
-
-
+
+
/*
* Look for server configuration items
* in the reply list.
log_debug("[%s]:%d WARNING! Check item \"%s\"\n"
"\tfound in reply item list for user \"%s\".\n"
"\tThis attribute MUST go on the first line"
- " with the other check items",
+ " with the other check items",
filename, entry->lineno, vp->name,
entry->name);
}
}
-
+
entry = entry->next;
}
-
+
}
*pair_list = users;
if((mainconfig.do_usercollide) && (strcmp(pl->name, "DEFAULT"))) {
- /*
+ /*
* We have to make sure the password
* matches as well
*/
-
+
/* Save the orginal config items */
check_save = paircopy(request->config_items);
-
+
/* Copy this users check pairs to the request */
check_tmp = paircopy(pl->check);
pairmove(check_pairs, &check_tmp);
pairfree(&check_tmp);
-
+
DEBUG2(" users: Checking %s at %d", pl->name, pl->lineno);
/* Check the req to see if we matched */
if (rad_check_password(request)==0) {
/* Free our saved config items */
pairfree(&check_save);
- /*
- * Already copied check items, so
+ /*
+ * Already copied check items, so
* just copy reply here
*/
reply_tmp = paircopy(pl->reply);
check_pairs = &request->config_items;
continue;
}
-
+
/* No usercollide */
} else {
-
+
DEBUG2(" users: Matched %s at %d", pl->name, pl->lineno);
found = 1;
check_tmp = paircopy(pl->check);
break;
}
}
-
+
/*
* See if we succeeded. If we didn't find the user,
* then exit from the module.
if (vp->flags.do_xlat) {
int rcode;
char buffer[sizeof(vp->strvalue)];
-
+
vp->flags.do_xlat = 0;
rcode = radius_xlat(buffer, sizeof(buffer),
vp->strvalue,
request, NULL);
-
+
/*
* Parse the string into
* a new value.
*
* Copyright 2001 The FreeRADIUS server project
* Copyright 2002 Kostas Kalevras <kkalev@noc.ntua.gr>
- *
+ *
* March 2002, Kostas Kalevras <kkalev@noc.ntua.gr>
* - Initial release
* April 2002, Kostas Kalevras <kkalev@noc.ntua.gr>
unsigned j;
const char *cli = "0";
char *pool_name = NULL;
-
+
/*
* Set up a storage area for instance data
*/
free(data);
return -1;
}
-
+
data->gdbm = gdbm_open(data->session_db, sizeof(int),
GDBM_WRCREAT | GDBM_IPPOOL_OPTS, 0600, NULL);
if (data->gdbm == NULL) {
ip_ntoa(str, ntohl(i)));
continue;
}
-
+
strcpy(key.nas, nas_init);
key.port = j;
key_datum.dptr = (char *) &key;
pthread_mutex_init(&data->op_mutex, NULL);
*instance = data;
-
+
return 0;
}
/*
* Check for an Accounting-Stop
- * If we find one and we have allocated an IP to this nas/port combination, deallocate it.
+ * If we find one and we have allocated an IP to this nas/port combination, deallocate it.
*/
static int ippool_accounting(void *instance, REQUEST *request)
{
memset(key.nas,0,MAX_NAS_NAME_SIZE);
strncpy(key.nas,nas,MAX_NAS_NAME_SIZE -1 );
- key.port = port;
+ key.port = port;
DEBUG("rlm_ippool: Searching for an entry for nas/port: %s/%u",key.nas,key.port);
key_datum.dptr = (char *) &key;
key_datum.dsize = sizeof(ippool_key);
pthread_mutex_lock(&data->op_mutex);
key_datum.dptr = NULL;
- if (cli != NULL){
+ if (cli != NULL){
key_datum = gdbm_firstkey(data->gdbm);
while(key_datum.dptr){
data_datum = gdbm_fetch(data->gdbm, key_datum);
if (data_datum.dptr){
memcpy(&entry,data_datum.dptr, sizeof(ippool_info));
- free(data_datum.dptr);
+ free(data_datum.dptr);
/*
* If we find an entry for the same caller-id and nas with active=1
* then we use that for multilink (MPPP) to work properly.
data_datum = gdbm_fetch(data->gdbm, key_datum);
if (data_datum.dptr){
memcpy(&entry,data_datum.dptr, sizeof(ippool_info));
- free(data_datum.dptr);
+ free(data_datum.dptr);
/*
* Find an entry with active == 0
*/
if (entry.active == 0){
- datum tmp;
+ datum tmp;
tmp.dptr = (char *) &entry.ipaddr;
tmp.dsize = sizeof(uint32_t);
data_datum = gdbm_fetch(data->ip, tmp);
-
+
/*
* If we find an entry in the ip index and the number is zero (meaning
* that we haven't allocated the same ip address to another nas/port pair)
* Else we don't delete the session entry since we haven't yet deallocated the
* corresponding ip address and we continue our search.
*/
-
+
if (data_datum.dptr){
memcpy(&num,data_datum.dptr, sizeof(int));
free(data_datum.dptr);
*/
datum key_datum_tmp;
datum data_datum_tmp;
- ippool_key key_tmp;
+ ippool_key key_tmp;
memset(key_tmp.nas,0,MAX_NAS_NAME_SIZE);
strncpy(key_tmp.nas,nas,MAX_NAS_NAME_SIZE -1 );
key.port = port;
key_datum.dptr = (char *) &key;
key_datum.dsize = sizeof(ippool_key);
-
+
DEBUG2("rlm_ippool: Allocating ip to nas/port: %s/%u",key.nas,key.port);
rcode = gdbm_store(data->gdbm, key_datum, data_datum, GDBM_REPLACE);
if (rcode < 0) {
/* Increase the ip index count */
key_datum.dptr = (char *) &entry.ipaddr;
- key_datum.dsize = sizeof(uint32_t);
+ key_datum.dsize = sizeof(uint32_t);
data_datum = gdbm_fetch(data->ip, key_datum);
if (data_datum.dptr){
memcpy(&num,data_datum.dptr,sizeof(int));
return RLM_MODULE_FAIL;
}
pthread_mutex_unlock(&data->op_mutex);
-
+
DEBUG("rlm_ippool: Allocated ip %s to client on nas %s,port %u",ip_ntoa(str,entry.ipaddr),
key.nas,port);
* is single-threaded.
*/
module_t rlm_ippool = {
- "IPPOOL",
+ "IPPOOL",
RLM_TYPE_THREAD_SAFE, /* type */
NULL, /* initialization */
ippool_instantiate, /* instantiation */
// Copyright 2003 by Edwin Groothuis, edwin@mavetju.org
// All rights reserved.
-//
+//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
-//
+//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
printf("rlm_ippool_tool: Unable to convert IP address '%s'\n", ipaddress);
return;
}
-
+
if (sessiondb==NULL)
{
printf("rlm_ippool_tool: Unable to open DB '%s'\n", sessiondbname);
return;
}
-
+
if (indexdb==NULL)
{
printf("rlm_ippool_tool: Unable to open DB '%s'\n", indexdbname);
}
port = strtoul(NASport,NULL,0);
-
+
/* Basically from rlm_ippool.c */
memset(key.nas,0,MAX_NAS_NAME_SIZE);
if (data_datum.dptr != NULL){
found = 1;
memcpy(&entry,data_datum.dptr, sizeof(ippool_info));
- free(data_datum.dptr);
+ free(data_datum.dptr);
if (entry.active){
printf("rlm_ippool_tool: Deleting stale entry for ip/port %s/%u",
ipaddress, port);
}
key_datum.dptr = NULL;
- if (cli != NULL){
+ if (cli != NULL){
key_datum = gdbm_firstkey(sessiondb);
while(key_datum.dptr){
data_datum = gdbm_fetch(sessiondb, key_datum);
if (data_datum.dptr){
memcpy(&entry,data_datum.dptr, sizeof(ippool_info));
- free(data_datum.dptr);
+ free(data_datum.dptr);
/*
* If we find an entry for the same caller-id and nas with active=1
* then we use that for multilink (MPPP) to work properly.
/* Increase the ip index count */
key_datum.dptr = (char *) &entry.ipaddr;
- key_datum.dsize = sizeof(uint32_t);
+ key_datum.dsize = sizeof(uint32_t);
data_datum = gdbm_fetch(indexdb, key_datum);
if (data_datum.dptr){
memcpy(&num,data_datum.dptr,sizeof(int));
if ((argc==2 || argc==3) && !nflag) {
viewdb(argv[0],argv[1],argv[2]);
if (cflag) printf("%d\n",active);
- } else
+ } else
if (argc==5 && nflag)
addip(argv[0],argv[1],argv[2],argv[3],argv[4]);
else
* Actually perform the authentication
*/
memset((char *)&kcreds, 0, sizeof(kcreds));
-
+
if ( (r = krb5_parse_name(context, user, &kcreds.client)) ) {
radlog(L_AUTH, "rlm_krb5: [%s] krb5_parse_name failed: %s",
user, error_message(r));
krb5_cc_destroy(context, ccache);
return r;
}
-
+
return RLM_MODULE_REJECT;
}
userP->realm);
krb5_cc_default(context, &id);
-
+
ret = krb5_verify_user(context,
userP,
id,
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
- * This module is based on LDAP patch to Cistron radiusd by James Golovich
- * <james@wwnet.net>, which in turn was based mostly on a Mysql+Cistron patch
+ * This module is based on LDAP patch to Cistron radiusd by James Golovich
+ * <james@wwnet.net>, which in turn was based mostly on a Mysql+Cistron patch
* from <oyarzun@wilmington.net>
- *
+ *
* 17 Jan 2000, Adrian Pavlykevych <pam@polynet.lviv.ua>
* - OpenLDAP SDK porting, basic TLS support, LDAP authorization,
- * fault tolerance with multiple LDAP server support
- * 24 May 2000, Adrian Pavlykevych <pam@polynet.lviv.ua>
+ * fault tolerance with multiple LDAP server support
+ * 24 May 2000, Adrian Pavlykevych <pam@polynet.lviv.ua>
* - Converting to new configuration file format, futher improvements
* in fault tolerance, threaded operation
- * 12 Dec 2000, Adrian Pavlykevych <pam@polynet.lviv.ua>
+ * 12 Dec 2000, Adrian Pavlykevych <pam@polynet.lviv.ua>
* - Added preliminary support for multiple instances
* - moved all instance configuration into dynamicly allocated structure
* - Removed connection maintenance thread and all attempts for multihreading
* - Support for generic RADIUS check and reply attribute.
* Jun 2001, Kostas Kalevras <kkalev@noc.ntua.gr>
* - Fix: check and reply attributes from LDAP _replace_ existing ones
- * - Added "default_profile" directive, which points to radiusProfile
+ * - Added "default_profile" directive, which points to radiusProfile
* object, which contains default values for RADIUS users
- * - Added "profile_attribute" directive, which specifies user object
+ * - Added "profile_attribute" directive, which specifies user object
* attribute pointing to radiusProfile object.
* Nov 2001, Kostas Kalevras <kkalev@noc.ntua.gr>
* - Added support for adding the user password to the check. Based on
return -1;
}
-
+
static inline void ldap_release_conn(int i, LDAP_CONN *conns)
{
DEBUG("ldap_release_conn: Release Id: %d",i);
* to create an instance of the module.
*
*************************************************************************/
-static int
+static int
ldap_instantiate(CONF_SECTION * conf, void **instance)
{
ldap_instance *inst;
inst->port = 0;
}
#endif
-
+
inst->timeout.tv_usec = 0;
inst->net_timeout.tv_usec = 0;
/* workaround for servers which support LDAPS but not START TLS */
inst->conns[i].failed_conns = 0;
inst->conns[i].ld = NULL;
pthread_mutex_init(&inst->conns[i].mutex, NULL);
- }
+ }
if (read_mappings(inst) != 0) {
radlog(L_ERR, "rlm_ldap: Reading dictionary mappings from file %s failed",
inst->dictionary_mapping);
radlog(L_ERR, "rlm_ldap: Proceeding with no mappings");
}
-
+
pair = inst->check_item_map;
while(pair != NULL){
atts_num++;
}
}
}
- inst->atts[atts_num] = NULL;
+ inst->atts[atts_num] = NULL;
DEBUG("conns: %p",inst->conns);
/* strip comments */
ptr = strchr(buf, '#');
if (ptr) *ptr = 0;
-
+
/* empty line */
if (buf[0] == 0) continue;
-
- /* extract tokens from the string */
+
+ /* extract tokens from the string */
token_count = sscanf(buf, "%s %s %s", itemType, radiusAttribute, ldapAttribute);
- if (token_count <= 0) /* no tokens */
+ if (token_count <= 0) /* no tokens */
continue;
if (token_count != 3) {
fclose(mapfile);
return -1;
}
-
+
/* push node to correct list */
if (strcasecmp(itemType, "checkItem") == 0) {
pair->next = inst->check_item_map;
pair->next = inst->reply_item_map;
inst->reply_item_map = pair;
} else {
- radlog(L_ERR, "rlm_ldap: file %s: skipping line %i: unknown itemType %s",
+ radlog(L_ERR, "rlm_ldap: file %s: skipping line %i: unknown itemType %s",
filename, linenumber, itemType);
free(pair->attr);
free(pair->radius_attr);
DEBUG("rlm_ldap: LDAP %s mapped to RADIUS %s",
pair->attr, pair->radius_attr);
}
-
+
fclose(mapfile);
return 0; /* success */
}
-static int
-perform_search(void *instance, LDAP_CONN *conn, char *search_basedn, int scope, char *filter,
+static int
+perform_search(void *instance, LDAP_CONN *conn, char *search_basedn, int scope, char *filter,
char **attrs, LDAPMessage ** result)
{
int res = RLM_MODULE_OK;
radlog(L_INFO, "rlm_ldap: Attempting reconnect");
search_retry = 1;
conn->bound = 0;
- ldap_msgfree(*result);
+ ldap_msgfree(*result);
goto retry;
}
}
/* We don't need to reconnect in these cases so we don't set conn->bound */
ldap_get_option(conn->ld, LDAP_OPT_ERROR_NUMBER, &ldap_errno);
radlog(L_ERR, "rlm_ldap: ldap_search() failed: %s", ldap_err2string(ldap_errno));
- ldap_msgfree(*result);
+ ldap_msgfree(*result);
return (RLM_MODULE_FAIL);
default:
ldap_get_option(conn->ld, LDAP_OPT_ERROR_NUMBER, &ldap_errno);
radlog(L_ERR, "rlm_ldap: ldap_search() failed: %s", ldap_err2string(ldap_errno));
conn->bound = 0;
- ldap_msgfree(*result);
+ ldap_msgfree(*result);
return (RLM_MODULE_FAIL);
}
if ((ldap_count_entries(conn->ld, *result)) != 1) {
DEBUG("rlm_ldap: object not found or got ambiguous search result");
res = RLM_MODULE_NOTFOUND;
- ldap_msgfree(*result);
+ ldap_msgfree(*result);
}
return res;
}
static int ldap_escape_func(char *out, int outlen, const char *in)
{
int len = 0;
-
+
while (in[0]) {
/*
* Only one byte left.
if (outlen <= 1) {
break;
}
-
+
if (strchr("*", *in)) {
in++;
outlen--;
continue;
}
-
+
/*
* Else it's a nice character.
*/
/* This looks like a DN */
snprintf(filter,sizeof(filter), "%s",gr_filter);
snprintf(basedn,sizeof(basedn), "%s",(char *)check->strvalue);
- } else
+ } else
snprintf(filter,sizeof(filter), "(&(%s=%s)%s)",inst->groupname_attr,(char *)check->strvalue,gr_filter);
if ((conn_id = ldap_get_conn(inst->conns,&conn,inst)) == -1){
radlog(L_ERR, "rlm_ldap: All ldap connections are in use");
return 1;
}
-
+
if ((res = perform_search(inst, conn, basedn, LDAP_SCOPE_SUBTREE,
filter, attrs, &result)) == RLM_MODULE_OK){
DEBUG("rlm_ldap::ldap_groupcmp: User found in group %s",
ldap_release_conn(conn_id,inst->conns);
return 0;
}
-
+
ldap_release_conn(conn_id,inst->conns);
if (res != RLM_MODULE_NOTFOUND ) {
}
if (inst->groupmemb_attr == NULL){
- /* search returned NOTFOUND and searching for membership
+ /* search returned NOTFOUND and searching for membership
* using user object attributes is not specified in config
* file
*/
DEBUG("rlm_ldap::ldap_groupcmp: Search returned error");
ldap_release_conn(conn_id, inst->conns);
return 1;
- }
+ }
if ((msg = ldap_first_entry(conn->ld, result)) == NULL) {
DEBUG("rlm_ldap::ldap_groupcmp: ldap_first_entry() failed");
unsigned int i = 0;
char found = 0;
for (;i < ldap_count_values(vals);i++){
- if (strchr(vals[i],',') != NULL){
+ if (strchr(vals[i],',') != NULL){
/* This looks like a DN */
LDAPMessage *gr_result = NULL;
snprintf(filter,sizeof(filter), "(%s=%s)",
* Purpose: Check if user is authorized for remote access
*
******************************************************************************/
-static int
+static int
ldap_authorize(void *instance, REQUEST * request)
{
LDAPMessage *result = NULL;
}
/*
- * Check for the default profile entry. If it exists then add the
+ * Check for the default profile entry. If it exists then add the
* attributes it contains in the check and reply pairs
*/
profile = user_profile->strvalue;
if (profile && strlen(profile)){
if ((res = perform_search(instance, conn,
- profile, LDAP_SCOPE_BASE,
+ profile, LDAP_SCOPE_BASE,
filter, inst->atts, &def_result)) == RLM_MODULE_OK){
if ((def_msg = ldap_first_entry(conn->ld,def_result))){
if ((check_tmp = ldap_pairget(conn->ld,def_msg,inst->check_item_map,check_pairs,1))) {
}
}
ldap_msgfree(def_result);
- } else
+ } else
DEBUG("rlm_ldap: default_profile/user-profile search failed");
}
}
/*
- * Check for the profile attribute. If it exists, we assume that it
+ * Check for the profile attribute. If it exists, we assume that it
* contains the DN of an entry containg a profile for the user. That
* way we can have different general profiles for various user groups
* (students,faculty,staff etc)
strNcpy(filter,inst->base_filter,sizeof(filter));
while(vals[i] != NULL && strlen(vals[i])){
if ((res = perform_search(instance, conn,
- vals[i], LDAP_SCOPE_BASE,
+ vals[i], LDAP_SCOPE_BASE,
filter, inst->atts, &def_attr_result)) == RLM_MODULE_OK){
if ((def_attr_msg = ldap_first_entry(conn->ld,def_attr_result))){
if ((check_tmp = ldap_pairget(conn->ld,def_attr_msg,inst->check_item_map,check_pairs,1))) {
}
}
ldap_msgfree(def_attr_result);
- } else
+ } else
DEBUG("rlm_ldap: profile_attribute search failed");
i++;
}
* Purpose: Check the user's password against ldap database
*
*****************************************************************************/
-static int
+static int
ldap_authenticate(void *instance, REQUEST * request)
{
LDAP *ld_user;
}
- DEBUG("rlm_ldap: login attempt by \"%s\" with password \"%s\"",
+ DEBUG("rlm_ldap: login attempt by \"%s\" with password \"%s\"",
request->username->strvalue, request->password->strvalue);
while((vp_user_dn = pairfind(request->packet->vps, PW_LDAP_USERDN)) == NULL) {
if (!radius_xlat(filter, sizeof(filter), inst->filter,
request, NULL)) {
- radlog (L_ERR, "rlm_ldap: unable to create filter.\n");
+ radlog (L_ERR, "rlm_ldap: unable to create filter.\n");
return RLM_MODULE_INVALID;
}
break;
case LDAP_INVALID_CREDENTIALS:
- if (auth){
+ if (auth){
DEBUG("rlm_ldap: Bind failed with invalid credentials");
*result = RLM_MODULE_REJECT;
}
else {
radlog(L_ERR, "rlm_ldap: LDAP login failed: check login, password settings in ldap section of radiusd.conf");
*result = RLM_MODULE_FAIL;
- }
+ }
break;
-
+
default:
if (inst->is_url)
radlog(L_ERR,"rlm_ldap: %s bind to %s failed %s",
* Detach from the LDAP server and cleanup internal state.
*
*****************************************************************************/
-static int
+static int
ldap_detach(void *instance)
{
ldap_instance *inst = instance;
}
pair = inst->check_item_map;
-
+
while (pair != NULL) {
nextpair = pair->next;
free(pair->attr);
}
#ifdef FIELDCPY
-static void
+static void
fieldcpy(char *string, char **uptr)
{
char *ptr;
if (is_generic_attribute) {
/* this is a generic attribute */
LRAD_TOKEN dummy; /* makes pairread happy */
-
+
/* not sure if using pairread here is ok ... */
if ( (newpair = pairread(&ptr, &dummy)) != NULL) {
- DEBUG("rlm_ldap: extracted attribute %s from generic item %s",
+ DEBUG("rlm_ldap: extracted attribute %s from generic item %s",
newpair->name, vals[vals_idx]);
pairadd(&pairlist, newpair);
} else {
- radlog(L_ERR, "rlm_ldap: parsing %s failed: %s",
+ radlog(L_ERR, "rlm_ldap: parsing %s failed: %s",
element->attr, vals[vals_idx]);
}
} else {
/*
- * rlm_mschap.c
+ * rlm_mschap.c
*
* Version: $Id$
*
* aka
* ZARAZA 3APA3A@security.nnov.ru
*/
-
+
/* MPPE support from Takahiro Wagatsuma <waga@sic.shibaura-it.ac.jp> */
#include "autoconf.h"
{
char * c1, * c2;
int i;
-
+
for (i = 0; i < len; i++) {
if( !(c1 = memchr(letters, toupper((int) szHex[i << 1]), 16)) ||
!(c2 = memchr(letters, toupper((int) szHex[(i << 1) + 1]), 16)))
/*
* bin2hex creates hexadecimal presentation
* of binary data
- */
+ */
static void bin2hex (const unsigned char *szBin, char *szHex, int len)
{
int i;
break;
case 'D': /* 'D'isabled. */
- acct_ctrl |= ACB_DISABLED ;
+ acct_ctrl |= ACB_DISABLED ;
break;
case 'H': /* 'H'omedir required. */
case ':':
case '\n':
- case '\0':
+ case '\0':
case ']':
default:
finished = 1;
{
SHA1_CTX Context;
char hash[20];
-
+
SHA1Init(&Context);
SHA1Update(&Context, peer_challenge, 16);
SHA1Update(&Context, auth_challenge, 16);
char *response)
{
char challenge[8];
-
+
challenge_hash(peer_challenge, auth_challenge, user_name,
challenge);
0x65, 0x72, 0x20, 0x74, 0x6F, 0x20, 0x63, 0x6C, 0x69, 0x65,
0x6E, 0x74, 0x20, 0x73, 0x69, 0x67, 0x6E, 0x69, 0x6E, 0x67,
0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x74};
-
+
const char magic2[41] =
{0x50, 0x61, 0x64, 0x20, 0x74, 0x6F, 0x20, 0x6D, 0x61, 0x6B,
0x65, 0x20, 0x69, 0x74, 0x20, 0x64, 0x6F, 0x20, 0x6D, 0x6F,
offsetof(struct mschap_instance, passwd_file), NULL, NULL },
{ "authtype", PW_TYPE_STRING_PTR,
offsetof(struct mschap_instance, auth_type), NULL, NULL },
-
+
{ NULL, -1, 0, NULL, NULL } /* end the list */
};
return 0;
#undef inst
}
-
+
/*
* Create instance for our module. Allocate space for
* instance structure and read configuration parameters
if (!challenge) {
return RLM_MODULE_NOOP;
}
-
+
response = pairfind(request->packet->vps, PW_MSCHAP_RESPONSE);
if (!response)
response = pairfind(request->packet->vps, PW_MSCHAP2_RESPONSE);
* or in configured passwd file.
* If one is found we will check paraneters given by NAS.
*
- * If PW_SMB_ACCOUNT_CTRL is not set to ACB_PWNOTREQ we must have
+ * If PW_SMB_ACCOUNT_CTRL is not set to ACB_PWNOTREQ we must have
* one of:
* PAP: PW_PASSWORD or
* MS-CHAP: PW_MSCHAP_CHALLENGE and PW_MSCHAP_RESPONSE or
uint8_t mppe_recvkey[34];
char *username_string;
int chap = 0;
-
+
/*
* Find the SMB-Account-Ctrl attribute, or the
* SMB-Account-Ctrl-Text attribute.
DEBUG2(" rlm_mschap: No LM-Password or NT-Password attribute found. Cannot perform MS-CHAP authentication.");
return RLM_MODULE_FAIL;
}
-
+
/*
* We MAY be asked to take a User-Password attribute from
* the packet, and compare it to passwords retrieved from
radlog(L_AUTH, "rlm_mschap: MS-CHAP-Challenge has the wrong format.");
return RLM_MODULE_INVALID;
}
-
+
/*
* Responses are 50 octets.
*/
radlog(L_AUTH, "rlm_mschap: MS-CHAP-Response has the wrong format.");
return RLM_MODULE_INVALID;
}
-
+
/*
* We are doing MS-CHAP. Calculate the MS-CHAP
* response
DEBUG2(" rlm_mschap: FAILED: No NT/LM-Password");
return RLM_MODULE_REJECT;
}
-
+
/*
* Calculate the expected response.
*/
radlog(L_AUTH, "rlm_mschap: MS-CHAP-Challenge has the wrong format.");
return RLM_MODULE_INVALID;
}
-
+
/*
* Responses are 50 octets.
*/
} else {
username_string = username->strvalue;
}
-
+
/*
* We are doing MS-CHAPv2
* We need NT hash for it to calculate response
add_reply( &request->reply->vps, *response->strvalue,
"MS-CHAP2-Success", msch2resp, 42);
chap = 2;
-
+
} else { /* Neither CHAPv1 or CHAPv2 response: die */
radlog(L_AUTH, "rlm_mschap: No MS-CHAP response found");
return RLM_MODULE_INVALID;
}
if (nt_password) {
- /*
+ /*
* According to RFC 2548 we
* should send NT hash. But in
* practice it doesn't work.
nt_password->strvalue,
response->strvalue + 26,
mppe_sendkey, mppe_recvkey);
-
+
mppe_add_reply(&request->reply->vps,
"MS-MPPE-Recv-Key",
mppe_recvkey, 16);
mppe_add_reply(&request->reply->vps,
"MS-MPPE-Send-Key",
mppe_sendkey, 16);
-
+
}
reply_attr = pairmake("MS-MPPE-Encryption-Policy",
(inst->require_encryption)? "0x00000002":"0x00000001",
T_OP_EQ);
rad_assert(reply_attr != NULL);
pairadd(&request->reply->vps, reply_attr);
-
+
} /* else we weren't asked to use MPPE */
return RLM_MODULE_OK;
char hash[16];
char ntpass[33];
char lmpass[33];
-
+
fprintf(stderr, "LM Hash \tNT Hash\n");
fprintf(stderr, "--------------------------------\t--------------------------------\n");
fflush(stderr);
* Taken from the hacks for qmail located at nrg4u.com
* by Andre Oppermann.
*
- * NS-MTA-MD5 passwords are 64 byte strings, the first
- * 32 bytes being the password hash and the last 32 bytes
- * the salt. The clear text password and the salt are MD5
+ * NS-MTA-MD5 passwords are 64 byte strings, the first
+ * 32 bytes being the password hash and the last 32 bytes
+ * the salt. The clear text password and the salt are MD5
* hashed[1]. If the resulting hash concatenated with the salt
- * are equivalent to the original NS-MTA-MD5 password the
- * password is correct.
+ * are equivalent to the original NS-MTA-MD5 password the
+ * password is correct.
*
* [1] Read the source for details.
*
static int module_auth(void *instance, REQUEST *request)
{
VALUE_PAIR *md5_password;
-
+
/*
* We can only authenticate user requests which HAVE
* a User-Password attribute.
struct pam_response *reply = NULL;
int size = sizeof(struct pam_response);
my_PAM *pam_config = (my_PAM *) appdata_ptr;
-
+
#define GET_MEM if (reply) realloc(reply, size); else reply = rad_malloc(size); \
size += sizeof(struct pam_response)
#define COPY_STRING(s) ((s) ? strdup(s) : NULL)
-
+
for (count = 0; count < num_msg; count++) {
switch (msg[count]->msg_style) {
case PAM_PROMPT_ECHO_ON:
*************************************************************************/
/* cjd 19980706
- *
+ *
* for most flexibility, passing a pamauth type to this function
* allows you to have multiple authentication types (i.e. multiple
* files associated with radius in /etc/pam.d)
char *pch = str;
char ch;
int i;
-
+
for(i = 0;i < len; i ++) {
ch = pch[i];
buffer[2*i] = pap_hextab[(ch>>4) & 15];
return RLM_MODULE_INVALID;
}
- DEBUG("rlm_pap: login attempt by \"%s\" with password %s",
+ DEBUG("rlm_pap: login attempt by \"%s\" with password %s",
request->username->strvalue, request->password->strvalue);
if (((passwd_item = pairfind(request->config_items, PW_PASSWORD)) == NULL) ||
DEBUG("rlm_pap: Using password \"%s\" for user %s authentication.",
passwd_item->strvalue, request->username->strvalue);
-
+
if (inst->sch == PAP_ENC_INVALID || inst->sch > PAP_MAX_ENC){
radlog(L_ERR, "rlm_pap: Wrong password scheme");
return RLM_MODULE_FAIL;
* is single-threaded.
*/
module_t rlm_pap = {
- "PAP",
+ "PAP",
0, /* type */
NULL, /* initialization */
pap_instantiate, /* instantiation */
h = h * 7907 + *username++;
}
return h%tablesize;
-}
+}
static void release_hash_table(struct hashtable * ht){
int i;
if (!ht) return;
- for (i=0; i<ht->tablesize; i++)
+ for (i=0; i<ht->tablesize; i++)
if (ht->table[i])
destroy_password(ht->table[i]);
if (ht->table) free(ht->table);
char *list;
char *nextlist=0;
int i;
-
+
ht = (struct hashtable *) rad_malloc(sizeof(struct hashtable));
if(!ht) {
return NULL;
free(hashentry);
continue;
}
-
+
if (islist) {
list = hashentry->field[keyfield];
for (nextlist = list; *nextlist && *nextlist!=','; nextlist++);
char buffer[1024];
int len;
char *list, *nextlist;
-
+
if (ht->tablesize > 0) {
/* get saved address of next item to check from buffer */
hashentry = ht->last_found;
if(!strcmp(list, name)) return passwd;
}
}
-
+
}
}
fclose(ht->fp);
{
int h;
struct mypasswd * hashentry;
-
+
if (!ht || !name || *name == '\0') return NULL;
ht->last_found = NULL;
if (ht->tablesize > 0) {
char *buffer;
struct mypasswd* pw;
int i;
-
+
ht = build_hash_table("/etc/group", 4, 3, 1, 100, 0, ":");
if(!ht) {
printf("Hash table not built\n");
static CONF_PARSER module_config[] = {
{ "filename", PW_TYPE_STRING_PTR,
- offsetof(struct passwd_instance, filename), NULL, NULL },
+ offsetof(struct passwd_instance, filename), NULL, NULL },
{ "format", PW_TYPE_STRING_PTR,
offsetof(struct passwd_instance, format), NULL, NULL },
{ "authtype", PW_TYPE_STRING_PTR,
#define inst ((struct passwd_instance *)*instance)
int nfields=0, keyfield=-1, listable=0;
char *s;
- char *lf=NULL; /* destination list flags temporary */
+ char *lf=NULL; /* destination list flags temporary */
int len;
int i;
DICT_ATTR * da;
-
+
*instance = rad_malloc(sizeof(struct passwd_instance));
if ( !*instance) {
radlog(L_ERR, "rlm_passwd: cann't alloc instance");
if(*(s+1) == ','){
listable = 1;
s++;
- }
+ }
if(*(s+1) == '='){
lf[nfields]=1;
s++;
radlog(L_ERR, "rlm_passwd: no field market as key in format: %s", inst->format);
return -1;
}
- if (! (inst->ht = build_hash_table (inst->filename, nfields, keyfield, listable, inst->hashsize, inst->ignorenislike, inst->delimiter)) ){
+ if (! (inst->ht = build_hash_table (inst->filename, nfields, keyfield, listable, inst->hashsize, inst->ignorenislike, inst->delimiter)) ){
radlog(L_ERR, "rlm_passwd: can't build hashtable from passwd file");
return -1;
}
release_ht(inst->ht);
return -1;
}
-
+
memcpy(inst->pwdfmt->listflag, lf, nfields);
free(lf);
inst->listable = listable;
radlog(L_INFO, "rlm_passwd: nfields: %d keyfield %d(%s) listable: %s", nfields, keyfield, inst->pwdfmt->field[keyfield], listable?"yes":"no");
return 0;
-
+
#undef inst
}
{
int i;
VALUE_PAIR *newpair;
-
+
for (i=0; i<inst->nfields; i++) {
if (inst->pwdfmt->field[i] && *inst->pwdfmt->field[i] && pw->field[i] && i != inst->keyfield && inst->pwdfmt->listflag[i] == when) {
if (! (newpair = pairmake (inst->pwdfmt->field[i], pw->field[i], T_OP_EQ))) {
VALUE_PAIR * key;
struct mypasswd * pw;
int found = 0;
-
+
if(!request || !request->packet ||!request->packet->vps)
return RLM_MODULE_INVALID;
for (key = request->packet->vps;
pairadd (&request->config_items, key);
}
return RLM_MODULE_OK;
-
+
#undef inst
}
/*
- * rlm_perl.c
+ * rlm_perl.c
*
* Version: $Id$
*
typedef struct perl_inst {
/* Name of the perl module */
char *module;
-
+
/* Name of the functions for each module method */
char *func_authorize;
char *func_authenticate;
{ NULL, -1, 0, NULL, NULL } /* end the list */
};
-
+
/*
* man perlembed
- */
+ */
EXTERN_C void boot_DynaLoader(pTHX_ CV* cv);
/*
int max_request_per_clone;
int cleanup_delay;
perl_mutex mutex;
- time_t time_when_last_added;
+ time_t time_when_last_added;
} PERL_POOL;
static PERL_POOL perl_pool;
}
static void rlm_perl_close_handles(void **handles)
-{
+{
int i;
if (!handles) {
return;
- }
+ }
for (i=0; handles[i]; i++) {
radlog(L_DBG, "close 0x%lx\n", (unsigned long)handles[i]);
{
PerlInterpreter *clone;
UV clone_flags = CLONEf_KEEP_PTR_TABLE;
-
+
PERL_SET_CONTEXT(interp);
-
+
clone = perl_clone(interp, clone_flags);
- {
+ {
dTHXa(clone);
}
-
+
ptr_table_free(PL_ptr_table);
PL_ptr_table = NULL;
PERL_SET_CONTEXT(aTHX);
rlm_perl_clear_handles(aTHX);
-
+
return clone;
}
dTHXa(perl);
}
/*
- * FIXME: This shouldn't happen
+ * FIXME: This shouldn't happen
*
*/
while (PL_scopestack_ix > 1 ){
LEAVE;
}
-
+
perl_destruct(perl);
perl_free(perl);
}
static void rlm_destroy_perl(PerlInterpreter *perl)
-{
+{
void **handles;
-
+
dTHXa(perl);
PERL_SET_CONTEXT(perl);
-
+
handles = rlm_perl_get_handles(aTHX);
rlm_perl_destruct(perl);
rlm_perl_close_handles(handles);
prev = handle->prev;
next = handle->next;
-
+
if (prev == NULL) {
perl_pool.head = next;
} else {
prev->next = next;
}
-
+
if (next == NULL) {
perl_pool.tail = prev;
} else {
prev = handle->prev;
next = handle->next;
-
+
if ((next != NULL) ||
(prev != NULL)) {
if (next == NULL) {
if (prev == NULL) {
perl_pool.head = next;
next->prev = NULL;
-
+
} else {
prev->next = next;
if (perl_pool.max_clones == perl_pool.current_clones) {
return NULL;
}
-
+
handle = (POOL_HANDLE *)rad_malloc(sizeof(POOL_HANDLE));
-
+
if (!handle) {
radlog(L_ERR,"Could not find free memory for pool. Aborting");
return NULL;
- }
-
+ }
+
handle->prev = NULL;
handle->next = NULL;
handle->status = idle;
handle->clone = rlm_perl_clone();
- handle->request_count = 0;
+ handle->request_count = 0;
perl_pool.current_clones++;
move2tail(handle);
-
+
now = time(NULL);
perl_pool.time_when_last_added = now;
-
+
return handle;
}
-static POOL_HANDLE *pool_pop()
+static POOL_HANDLE *pool_pop()
{
POOL_HANDLE *handle;
POOL_HANDLE *found;
POOL_HANDLE *tmp;
/*
- * Lock the pool and be fast other thread maybe
+ * Lock the pool and be fast other thread maybe
* waiting for us to finish
*/
MUTEX_LOCK(&perl_pool.mutex);
-
+
found = NULL;
-
+
for (handle = perl_pool.head; handle ; handle = tmp) {
tmp = handle->next;
-
+
if (handle->status == idle){
found = handle;
break;
}
}
-
+
if (found == NULL) {
if (perl_pool.current_clones < perl_pool.max_clones ) {
-
+
found = pool_grow();
perl_pool.current_clones++;
radlog(L_ERR,"Cannot grow pool returning");
MUTEX_UNLOCK(&perl_pool.mutex);
return NULL;
- }
+ }
} else {
radlog(L_ERR,"reached maximum clones %d cannot grow",
perl_pool.current_clones);
}
move2tail(found);
- found->status = busy;
+ found->status = busy;
perl_pool.active_clones++;
found->request_count++;
/*
* Hurry Up
*/
MUTEX_UNLOCK(&perl_pool.mutex);
- radlog(L_DBG,"perl_pool: item 0x%lx asigned new request. Handled so far: %d",
+ radlog(L_DBG,"perl_pool: item 0x%lx asigned new request. Handled so far: %d",
(unsigned long) found->clone, found->request_count);
return found;
}
MUTEX_LOCK(&perl_pool.mutex);
handle->status = idle;
perl_pool.active_clones--;
-
+
spare = perl_pool.current_clones - perl_pool.active_clones;
radlog(L_DBG,"perl_pool total/active/spare [%d/%d/%d]"
- , perl_pool.current_clones, perl_pool.active_clones, spare);
+ , perl_pool.current_clones, perl_pool.active_clones, spare);
if (spare < perl_pool.min_spare_clones) {
t = perl_pool.min_spare_clones - spare;
}
static int init_pool (CONF_SECTION *conf) {
POOL_HANDLE *handle;
- int t;
-
+ int t;
+
MUTEX_INIT(&perl_pool.mutex);
-
+
/*
- * Read The Config
+ * Read The Config
*
*/
-
+
cf_section_parse(conf,NULL,pool_conf);
-
+
for(t = 0;t < perl_pool.start_clones ;t++){
if ((handle = pool_grow()) == NULL) {
return -1;
}
-
+
}
-
+
return 1;
}
#endif
}
perl_construct(interp);
- PL_perl_destruct_level = 2;
-
+ PL_perl_destruct_level = 2;
+
return 0;
-
+
}
static void xs_init(pTHX)
{
char *file = __FILE__;
-
+
/* DynaLoader is a special case */
- newXS("DynaLoader::boot_DynaLoader", boot_DynaLoader, file);
-
+ newXS("DynaLoader::boot_DynaLoader", boot_DynaLoader, file);
+
}
/*
*
* This is wrapper for radlog
- * Now users can call radiusd::radlog(level,msg) wich is the same
+ * Now users can call radiusd::radlog(level,msg) wich is the same
* calling radlog from C code.
* Boyan
*/
-static XS(XS_radiusd_radlog)
+static XS(XS_radiusd_radlog)
{
dXSARGS;
if (items !=2)
{
int level;
char *msg;
-
+
level = (int) SvIV(ST(0));
msg = (char *) SvPV(ST(1), PL_na);
-
+
/*
* Because 'msg' is a 'char *', we don't want '%s', etc.
* in it to give us printf-style vulnerabilities.
static int perl_xlat(void *instance, REQUEST *request, char *fmt, char * out,
int freespace, RADIUS_ESCAPE_STRING func)
{
-
+
PERL_INST *inst= (PERL_INST *) instance;
PerlInterpreter *perl;
char params[1024], *tmp_ptr, *ptr, *tmp;
int count, ret;
STRLEN n_a;
-
+
perl = interp;
#ifdef USE_ITHREADS
POOL_HANDLE *handle;
-
+
if ((handle = pool_pop()) == NULL) {
return 0;
}
-
+
perl = handle->clone;
radlog(L_DBG,"Found a interpetator 0x%lx",(unsigned long) perl);
{
dTHXa(perl);
}
-#endif
- {
+#endif
+ {
dSP;
ENTER;SAVETMPS;
-
+
/*
* Do an xlat on the provided string (nice recursive operation).
*/
while ((tmp_ptr = strtok(NULL, " ")) != NULL) {
XPUSHs(sv_2mortal(newSVpv(tmp_ptr,0)));
- }
+ }
PUTBACK;
-
+
count = call_pv(inst->func_xlat, G_SCALAR | G_EVAL);
SPAGAIN;
- if (SvTRUE(ERRSV)) {
+ if (SvTRUE(ERRSV)) {
radlog(L_ERR, "rlm_perl: perl_xlat exit %s\n",
SvPV(ERRSV,n_a));
return 0;
- }
+ }
- if (count > 0) {
+ if (count > 0) {
tmp = POPp;
ret = strlen(tmp);
strncpy(out,tmp,ret);
radlog(L_DBG,"rlm_perl: Len is %d , out is %s freespace is %d",
ret, out,freespace);
-
+
PUTBACK ;
FREETMPS ;
LEAVE ;
* that must be referenced in later calls, store a handle to it
* in *instance otherwise put a null pointer there.
*
- * Boyan:
+ * Boyan:
* Setup a hashes wich we will use later
- * parse a module and give him a chance to live
- *
+ * parse a module and give him a chance to live
+ *
*/
static int perl_instantiate(CONF_SECTION *conf, void **instance)
{
HV *rad_reply_hv = newHV();
HV *rad_check_hv = newHV();
HV *rad_request_hv = newHV();
-
+
char *embed[4], *xlat_name;
int exitstatus = 0, argc=0;
-
+
/*
* Set up a storage area for instance data
*/
inst = rad_malloc(sizeof(PERL_INST));
memset(inst, 0, sizeof(PERL_INST));
-
+
/*
* If the configuration parameters can't be parsed, then
* fail.
free(inst);
return -1;
}
-
+
embed[0] = NULL;
if (inst->perl_flags) {
embed[2] = "0";
argc = 3;
}
-
+
exitstatus = perl_parse(interp, xs_init, argc, embed, NULL);
#if PERL_REVISION >= 5 && PERL_VERSION >=8
xlat_name = cf_section_name2(conf);
if (xlat_name == NULL)
xlat_name = cf_section_name1(conf);
- if (xlat_name){
+ if (xlat_name){
inst->xlat_name = strdup(xlat_name);
- xlat_register(xlat_name, perl_xlat, inst);
- }
+ xlat_register(xlat_name, perl_xlat, inst);
+ }
+
+#ifdef USE_ITHREADS
-#ifdef USE_ITHREADS
-
if ((init_pool(conf)) == -1) {
radlog(L_ERR,"Couldn't init a pool of perl clones. Exiting");
return -1;
}
-
+
#endif
*instance = inst;
-
+
return 0;
}
/*
- * get the vps and put them in perl hash
+ * get the vps and put them in perl hash
* If one VP have multiple values it is added as array_ref
* Example for this is Cisco-AVPair that holds multiple values.
* Which will be available as array_ref in $RAD_REQUEST{'Cisco-AVPair'}
hv_clear(rad_hv);
nvp = paircopy(vp);
-
+
while (nvp != NULL) {
attr = nvp->attribute;
vpa = paircopy2(nvp,attr);
nvp = vpa;
}
}
-
+
/*
*
- * Verify that a Perl SV is a string and save it in FreeRadius
+ * Verify that a Perl SV is a string and save it in FreeRadius
* Value Pair Format
*
*/
char *val;
int val_len;
VALUE_PAIR *vpp;
-
+
if ((sv != NULL) && (SvPOK(sv))) {
val = SvPV(sv, val_len);
vpp = pairmake(key, val, T_OP_EQ);
/*
* Boyan :
- * Gets the content from hashes
+ * Gets the content from hashes
*/
-static int get_hv_content(HV *my_hv, VALUE_PAIR **vp)
+static int get_hv_content(HV *my_hv, VALUE_PAIR **vp)
{
SV *res_sv, **av_sv;
AV *av;
char *key;
I32 key_len, len, i, j;
int ret=0;
-
+
for (i = hv_iterinit(my_hv); i > 0; i--) {
res_sv = hv_iternextsv(my_hv,&key,&key_len);
if (SvROK(res_sv) && (SvTYPE(SvRV(res_sv)) == SVt_PVAV)) {
}
} else ret = pairadd_sv(vp, key, res_sv) + ret;
}
-
+
return ret;
}
/*
- * Call the function_name inside the module
+ * Call the function_name inside the module
* Store all vps in hashes %RAD_CHECK %RAD_REPLY %RAD_REQUEST
- *
- */
+ *
+ */
static int rlmperl_call(void *instance, REQUEST *request, char *function_name)
{
VALUE_PAIR *vp;
int exitstatus=0, count;
STRLEN n_a;
-
+
HV *rad_reply_hv;
HV *rad_check_hv;
HV *rad_request_hv;
#ifdef USE_ITHREADS
POOL_HANDLE *handle;
-
+
if ((handle = pool_pop()) == NULL) {
return RLM_MODULE_FAIL;
}
-
+
radlog(L_DBG,"found interpetator at address 0x%lx",(unsigned long) handle->clone);
- {
+ {
dTHXa(handle->clone);
PERL_SET_CONTEXT(handle->clone);
}
#endif
{
dSP;
-
+
ENTER;
SAVETMPS;
rad_check_hv = get_hv("RAD_CHECK",1);
rad_request_hv = get_hv("RAD_REQUEST",1);
-
-
+
+
perl_store_vps(request->reply->vps, rad_reply_hv);
perl_store_vps(request->config_items, rad_check_hv);
perl_store_vps(request->packet->vps, rad_request_hv);
vp = NULL;
-
-
- PUSHMARK(SP);
- /*
+
+
+ PUSHMARK(SP);
+ /*
* This way %RAD_xx can be pushed onto stack as sub parameters.
* XPUSHs( newRV_noinc((SV *)rad_request_hv) );
* XPUSHs( newRV_noinc((SV *)rad_reply_hv) );
* XPUSHs( newRV_noinc((SV *)rad_check_hv) );
* PUTBACK;
*/
-
+
count = call_pv(function_name, G_SCALAR | G_EVAL | G_NOARGS);
- SPAGAIN;
-
+ SPAGAIN;
+
if (count == 1) {
exitstatus = POPi;
if (exitstatus >= 100 || exitstatus < 0) {
exitstatus = RLM_MODULE_FAIL;
}
}
-
- PUTBACK;
+
+ PUTBACK;
FREETMPS;
LEAVE;
-
+
if (SvTRUE(ERRSV)) {
radlog(L_ERR, "rlm_perl: perl_embed:: module = %s , func = %s exit status= %s\n",
inst->module,
if ((get_hv_content(rad_reply_hv, &vp)) > 0 ) {
pairmove(&request->reply->vps, &vp);
pairfree(&vp);
- }
+ }
if ((get_hv_content(rad_check_hv, &vp)) > 0 ) {
pairmove(&request->config_items, &vp);
pairfree(&vp);
- }
+ }
#if 0
/*
radlog(L_ERR, "Invalid Accounting Packet");
return RLM_MODULE_INVALID;
}
-
+
switch (acctstatustype) {
case PW_STATUS_START:
-
+
if (((PERL_INST *)instance)->func_start_accounting) {
return rlmperl_call(instance, request,
((PERL_INST *)instance)->func_start_accounting);
}
}
/*
- * Check for simultaneouse-use
+ * Check for simultaneouse-use
*/
static int perl_checksimul(void *instance, REQUEST *request)
}
/*
- * Detach a instance give a chance to a module to make some internal setup ...
+ * Detach a instance give a chance to a module to make some internal setup ...
*/
static int perl_detach(void *instance)
-{
+{
PERL_INST *inst = (PERL_INST *) instance;
int exitstatus=0,count=0;
-
-#ifdef USE_ITHREADS
+
+#ifdef USE_ITHREADS
POOL_HANDLE *handle;
-
+
for (handle = perl_pool.head; handle; handle = handle->next) {
-
+
radlog(L_INFO,"Detach perl 0x%lx", (unsigned long) handle->clone);
/*
- * Wait until clone becomes idle
+ * Wait until clone becomes idle
*
*/
while (handle->status == busy) {
}
-
+
/*
* Give a clones chance to run detach function
*/
dSP; PUSHMARK(SP);
count = call_pv(inst->func_detach, G_SCALAR | G_EVAL );
SPAGAIN;
-
+
if (count == 1) {
exitstatus = POPi;
/*
/*
*
* FIXME: For more efficienty we don't
- * free entire pool. We only reread config flags thus way
+ * free entire pool. We only reread config flags thus way
* we can extend pool_size.
- *
+ *
*/
{
dTHXa(interp);
PERL_SET_CONTEXT(interp);
-#endif /* USE_ITHREADS */
+#endif /* USE_ITHREADS */
{
dSP;
- PUSHMARK(SP);
+ PUSHMARK(SP);
count = call_pv(inst->func_detach, G_SCALAR | G_EVAL );
SPAGAIN;
-
+
if (count == 1) {
exitstatus = POPi;
if (exitstatus >= 100 || exitstatus < 0) {
RLM_TYPE_THREAD_SAFE, /* type */
#else
RLM_TYPE_THREAD_UNSAFE,
-#endif
+#endif
perl_init, /* initialization */
perl_instantiate, /* instantiation */
{
perl_authenticate,
perl_authorize,
perl_preacct,
- perl_accounting,
+ perl_accounting,
perl_checksimul, /* check simul */
NULL, /* pre-proxy */
NULL, /* post-proxy */
if (((dattr = dict_attrbyname(newattr)) != NULL) &&
(dattr->type == PW_TYPE_STRING)) {
VALUE_PAIR *newvp;
-
+
/*
* Make a new attribute.
*/
*/
request_pairs = request->packet->vps;
namepair = pairfind(request_pairs, PW_USER_NAME);
- if ((namepair == NULL) ||
+ if ((namepair == NULL) ||
(namepair->length <= 0)) {
return;
}
if (hints == NULL || request_pairs == NULL)
return RLM_MODULE_NOOP;
- /*
- * Check for valid input, zero length names not permitted
+ /*
+ * Check for valid input, zero length names not permitted
*/
if ((tmp = pairfind(request_pairs, PW_USER_NAME)) == NULL)
name = NULL;
radlog(L_ERR, "No memory");
exit(1);
}
-
+
strNcpy(vp->strvalue, i->name,
sizeof(vp->strvalue));
vp->length = strlen(vp->strvalue);
/*
- * rlm_python.c
+ * rlm_python.c
*
*
* This program is free software; you can redistribute it and/or modify
/* Names of modules */
char
*mod_instantiate,
- *mod_authorize,
+ *mod_authorize,
*mod_authenticate,
*mod_preacct,
*mod_accounting,
/* Names of functions */
*func_instantiate,
- *func_authorize,
+ *func_authorize,
*func_authenticate,
*func_preacct,
*func_accounting,
PyErr_Fetch(&pType, &pValue, &pTraceback);
pStr1 = PyObject_Str(pType);
pStr2 = PyObject_Str(pValue);
-
+
radlog(L_ERR, "%s: %s\n",
PyString_AsString(pStr1), PyString_AsString(pStr2));
}
if (pValue == Py_None) {
return;
}
-
+
if (!PyTuple_Check(pValue)) {
radlog(L_ERR, "%s: non-tuple passed", function_name);
}
/* Get the tuple size. */
outertuplesize = PyTuple_Size(pValue);
-
+
for (i = 0; i < outertuplesize; i++) {
PyObject *pTupleElement = PyTuple_GetItem(pValue, i);
-
+
if ((pTupleElement != NULL) &&
(PyTuple_Check(pTupleElement))) {
/* Check if it's a pair */
int tuplesize;
-
+
if ((tuplesize = PyTuple_Size(pTupleElement)) != 2) {
radlog(L_ERR, "%s: tuple element %d is a tuple "
" of size %d. must be 2\n", function_name,
}
else {
PyObject *pString1, *pString2;
-
+
pString1 = PyTuple_GetItem(pTupleElement, 0);
pString2 = PyTuple_GetItem(pTupleElement, 1);
const char *s1, *s2;
-
+
/* pairmake() will convert and find any
* errors in the pair.
*/
PyObject *pValue, *pValuePairContainer, **pValueHolder, **pValueHolderPtr;
int i, n_tuple, return_value;
-
+
/* Return with "OK, continue" if the function is not defined. */
if (pFunc == NULL) {
return RLM_MODULE_OK;
/* Default return value is "OK, continue" */
return_value = RLM_MODULE_OK;
-
- /* We will pass a tuple containing (name, value) tuples
+
+ /* We will pass a tuple containing (name, value) tuples
* We can safely use the Python function to build up a tuple,
* since the tuple is not used elsewhere.
*
n_tuple++;
}
}
-
+
/* Create the tuple and a holder for the pointers, so that we can
* decref more efficiently later without the overhead of reading
* the tuple.
if (NULL == (pValueHolder = pValueHolderPtr =
malloc(sizeof(PyObject *) * n_tuple))) {
-
+
radlog(L_ERR, "%s: malloc of %d bytes failed\n",
function_name, sizeof(PyObject *) * n_tuple);
-
+
return -1;
}
}
else {
pValuePairContainer = PyTuple_New(n_tuple);
-
+
i = 0;
for (vp = request->packet->vps; vp; vp = vp->next) {
PyObject *pValuePair, *pString1, *pString2;
-
+
/* The inside tuple has two only: */
pValuePair = PyTuple_New(2);
-
+
/* The name. logic from vp_prints, lib/print.c */
if (vp->flags.has_tag) {
snprintf(buf, BUF_SIZE, "%s:%d", vp->name, vp->flags.tag);
else {
strcpy(buf, vp->name);
}
-
+
pString1 = PyString_FromString(buf);
PyTuple_SetItem(pValuePair, 0, pString1);
-
-
+
+
/* The value. Use delimiter - don't know what that means */
vp_prints_value(buf, sizeof(buf), vp, 1);
pString2 = PyString_FromString(buf);
PyTuple_SetItem(pValuePair, 1, pString2);
-
+
/* Put the tuple inside the container */
PyTuple_SetItem(pValuePairContainer, i++, pValuePair);
-
+
/* Store the pointer in our malloc() storage */
*pValueHolderPtr++ = pValuePair;
}
}
-
+
/* Call Python function.
*/
-
+
if (pFunc && PyCallable_Check(pFunc)) {
PyObject *pArgs;
-
+
/* call the function with a singleton tuple containing the
* container tuple.
*/
radlog(L_ERR, "%s: could not set tuple item", function_name);
return -1;
}
-
+
if ((pValue = PyObject_CallObject(pFunc, pArgs)) == NULL) {
radlog(L_ERR, "%s: function call failed", function_name);
python_error();
return -1;
}
-
+
/* The function returns either:
* 1. tuple containing the integer return value,
* then the integer reply code (or None to not set),
else {
/* Now have the return value */
return_value = PyInt_AsLong(pTupleInt);
-
+
/* Reply item tuple */
add_vp_tuple(&request->reply->vps,
PyTuple_GetItem(pValue, 1), function_name);
/* Decrease reference count for the tuples passed, the
* container tuple, and the return value.
*/
-
+
pValueHolderPtr = pValueHolder;
i = n_tuple;
while (i--) {
}
free(pValueHolder);
Py_DECREF(pValuePairContainer);
-
+
/* pDict and pFunc are borrowed and must not be Py_DECREF-ed */
/* Free pairs if we are rejecting.
* xxx Shouldn't the core do that?
*/
-
+
if ((return_value == RLM_MODULE_REJECT) && (request != NULL)) {
pairfree(&(request->reply->vps));
}
-
+
/* Return the specified by the Python module */
return return_value;
}
} else {
PyObject *pName;
- pName = PyString_FromString(module);
+ pName = PyString_FromString(module);
Py_INCREF(pName);
*pyModule = PyImport_Import(pName);
Py_DECREF(pName);
free(data);
return -1;
}
-
+
/*
* Setup our 'radiusd' module.
*/
-
+
/* Code */
if ((module = data->pModule_builtin =
Py_InitModule3("radiusd", radiusd_methods,
free(data);
return -1;
}
-
+
/*
* Load constants into module
*/
/* Wrapper functions */
static int python_authorize(void *instance, REQUEST *request)
{
- return python_function(request,
+ return python_function(request,
((struct rlm_python_t *)instance)->pFunc_authorize,
"authorize");
}
static int python_authenticate(void *instance, REQUEST *request)
{
return python_function(
- request,
+ request,
((struct rlm_python_t *)instance)->pFunc_authenticate,
"authenticate");
}
static int python_preacct(void *instance, REQUEST *request)
{
return python_function(
- request,
+ request,
((struct rlm_python_t *)instance)->pFunc_preacct,
"preacct");
}
static int python_accounting(void *instance, REQUEST *request)
{
return python_function(
- request,
+ request,
((struct rlm_python_t *)instance)->pFunc_accounting,
"accounting");
}
static int python_checksimul(void *instance, REQUEST *request)
{
return python_function(
- request,
+ request,
((struct rlm_python_t *)instance)->pFunc_checksimul,
"checksimul");
}
static int python_detach(void *instance)
{
int return_value;
-
+
/* Default return value is failure */
return_value = -1;
if (((rlm_python_t *)instance)->pFunc_detach &&
PyCallable_Check(((rlm_python_t *)instance)->pFunc_detach)) {
-
+
PyObject *pArgs, *pValue;
-
+
/* call the function with an empty tuple */
pArgs = PyTuple_New(0);
pValue = PyObject_CallObject(((rlm_python_t *)instance)->pFunc_detach,
pArgs);
-
+
if (pValue == NULL) {
python_error();
return -1;
#endif
radlog(L_DBG, "python_detach done");
-
+
/* Return the specified by the Python module */
return return_value;
}
* is single-threaded.
*/
module_t rlm_python = {
- "python",
+ "python",
RLM_TYPE_THREAD_SAFE, /* type */
python_init, /* initialization */
python_instantiate, /* instantiation */
/*
- * rlm_radutmp.c
+ * rlm_radutmp.c
*
* Version: $Id$
*
* Lock the utmp file, prefer lockf() over flock().
*/
rad_lockfd(fd, LOCK_LEN);
-
+
/*
* Find the entry for this NAS / portno combination.
*/
* Lock the utmp file, prefer lockf() over flock().
*/
rad_lockfd(fd, LOCK_LEN);
-
+
/*
* Find the entry for this NAS / portno combination.
*/
ut.nas_port)) != NULL) {
lseek(fd, (off_t)cache->offset, SEEK_SET);
}
-
+
r = 0;
off = 0;
while (read(fd, &u, sizeof(u)) == sizeof(u)) {
if (u.nas_address != ut.nas_address ||
u.nas_port != ut.nas_port)
continue;
-
+
/*
* Don't compare stop records to unused entries.
*/
r = -1;
break;
}
-
+
if (status == PW_STATUS_START &&
strncmp(ut.session_id, u.session_id,
sizeof(u.session_id)) == 0 &&
r = -1;
break;
}
-
+
/*
* FIXME: the ALIVE record could need
* some more checking, but anyway I'd
if (u.login[0] != 0)
just_an_update = 1;
}
-
+
if (lseek(fd, -(off_t)sizeof(u), SEEK_CUR) < 0) {
radlog(L_ERR, "rlm_radutmp: negative lseek!");
lseek(fd, (off_t)0, SEEK_SET);
cache->next = inst->nas_port_list;
inst->nas_port_list = cache;
}
-
+
ut.type = P_LOGIN;
write(fd, &ut, sizeof(u));
}
-
+
/*
* The user has logged off, delete the entry by
* re-writing it in place.
if ((vp = pairfind(request->packet->vps, PW_FRAMED_IP_ADDRESS)) != NULL)
ipno = vp->lvalue;
if ((vp = pairfind(request->packet->vps, PW_CALLING_STATION_ID)) != NULL)
- call_num = vp->strvalue;
+ call_num = vp->strvalue;
/*
* lock the file while reading/writing.
rcode = rad_check_ts(u.nas_address, u.nas_port,
utmp_login, session_id);
rad_lockfd(fd, LOCK_LEN);
-
+
/*
* Failed to check the terminal server for
* duplicate logins: Return an error.
/*
- * rlm_realm.c
+ * rlm_realm.c
*
* Version: $Id$
*
{
case REALM_FORMAT_SUFFIX:
-
+
/* DEBUG2(" rlm_realm: Checking for suffix after \"%c\"", inst->delim[0]); */
- realmname = strrchr(username, 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';
username = ptr;
}
break;
-
+
default:
realmname = NULL;
break;
return NULL;
}
DEBUG2(" rlm_realm: Found realm \"%s\"", realm->realm);
-
+
/*
* If we've been told to strip the realm off, then do so.
*/
DEBUG2(" rlm_realm: Unknown packet code %d\n",
request->packet->code);
return NULL; /* don't do anything */
-
+
/*
* Perhaps accounting proxying was turned off.
*/
radlog(L_ERR|L_CONS, "no memory");
exit(1);
}
-
+
/*
* Add it, even if it's already present.
*/
-
+
/*
* Examine a request for a username with an realm, and if it
if (!name)
return RLM_MODULE_OK;
-
+
/*
* Check if we've got to proxy the request.
imsicount = 0;
lineno = 0;
-
+
while(fgets(tripbuf, sizeof(tripbuf), triplets) == tripbuf
&& imsicount < 3)
{
/* complain about malformed line */
continue;
}
-
-
+
+
r = paircreate(ATTRIBUTE_EAP_SIM_RAND1 + imsicount, PW_TYPE_OCTETS);
r = pairparsevalue(r, chal);
pairadd(reply_pairs, r);
-
+
k = paircreate(ATTRIBUTE_EAP_SIM_KC1 + imsicount, PW_TYPE_OCTETS);
k = pairparsevalue(k, kc);
rad_assert(k != NULL);
pairadd(reply_pairs, k);
-
+
s = paircreate(ATTRIBUTE_EAP_SIM_SRES1 + imsicount, PW_TYPE_OCTETS);
s = pairparsevalue(s, sres);
pairadd(reply_pairs, s);
-
+
imsicount++;
}
fclose(triplets);
-
+
if (imsicount < 3)
{
DEBUG("rlm_sim_files: "
- "insufficient number of challenges for imsi %s: %d\n",
+ "insufficient number of challenges for imsi %s: %d\n",
name, imsicount);
return RLM_MODULE_NOTFOUND;
}
-
+
DEBUG("rlm_sim_files: "
"authorized user/imsi %s\n", name);
-/*
+/*
Unix SMB/Netbios implementation.
Version 1.9.
SMB Byte handling
Copyright (C) Andrew Tridgell 1992-1995
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
- This file implements macros for machine independent short and
+ This file implements macros for machine independent short and
int manipulation
*/
#undef CAREFUL_ALIGNMENT
-/* we know that the 386 can handle misalignment and has the "right"
+/* we know that the 386 can handle misalignment and has the "right"
byteorder */
#ifdef __i386__
#define CAREFUL_ALIGNMENT 0
alignment errors */
/*
WARNING: This section is dependent on the length of int16 and int32
- being correct
+ being correct
*/
#define SVAL(buf,pos) (*(uint16 *)((char *)(buf) + (pos)))
#define IVAL(buf,pos) (*(uint32 *)((char *)(buf) + (pos)))
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
int temp;
/* If we are on a Bezerkeley system, use sigvec, else sigaction */
#ifndef SA_RESTART
- struct sigvec invec, outvec;
+ struct sigvec invec, outvec;
#else
struct sigaction inact, outact;
#endif
if (bytes_read <= 0) { /* Error so return */
- if (bytes_read < 0)
+ if (bytes_read < 0)
RFCNB_errno = RFCNBE_BadRead;
else
RFCNB_errno = RFCNBE_ConGone;
return(RFCNBE_Bad);
}
-
+
rest = rest - bytes_read;
}
/* Send an RFCNB packet to the connection.
- We just send each of the blocks linked together ...
+ We just send each of the blocks linked together ...
- If we can, try to send it as one iovec ...
+ If we can, try to send it as one iovec ...
*/
this_len = pkt_ptr -> len;
this_data = pkt_ptr -> data;
- if ((tot_sent + this_len) > len)
+ if ((tot_sent + this_len) > len)
this_len = len - tot_sent; /* Adjust so we don't send too much */
/* Now plug into the iovec ... */
/* Set up an alarm if timeouts are set ... */
- if (RFCNB_Timeout > 0)
+ if (RFCNB_Timeout > 0)
alarm(RFCNB_Timeout);
if ((len_sent = writev(con -> fd, io_list, i)) < 0) { /* An error */
}
-/* Read an RFCNB packet off the connection.
+/* Read an RFCNB packet off the connection.
We read the first 4 bytes, that tells us the length, then read the
- rest. We should implement a timeout, but we don't just yet
+ rest. We should implement a timeout, but we don't just yet
*/
/* We discard keep alives here ... */
- if (RFCNB_Timeout > 0)
+ if (RFCNB_Timeout > 0)
alarm(RFCNB_Timeout);
while (seen_keep_alive) {
#ifdef RFCNB_DEBUG
fprintf(stderr, "Connection closed reading\n");
-#endif
+#endif
- if (errno == EINTR)
+ if (errno == EINTR)
RFCNB_errno = RFCNBE_Timeout;
else
RFCNB_errno = RFCNBE_ConGone;
#ifdef RFCNB_DEBUG
fprintf(stderr, "RFCNB KEEP ALIVE received\n");
#endif
-
+
}
else {
seen_keep_alive = FALSE;
}
}
-
+
/* What if we got less than or equal to a hdr size in bytes? */
if (read_len < sizeof(hdr)) { /* We got a small packet */
#ifdef RFCNB_DEBUG
fprintf(stderr, "Reading Pkt: Length = %i\n", pkt_len);
-#endif
+#endif
/* Now copy in the hdr */
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
struct RFCNB_Hdr hdr;
unsigned char error;
-
+
} RFCNB_Nack_Pkt;
typedef struct RFCNB_Retarget_Pkt {
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
if (i >= len) {
c1 = 'C'; c2 = 'A'; /* CA is a space */
-
+
} else {
c = name1[i];
Uses the encoding in RFC1001. Each nibble of byte is added to 'A'
to produce the next byte in the name.
- This routine assumes that AName is 16 bytes long and that NBName has
- space for 32 chars, so be careful ...
+ This routine assumes that AName is 16 bytes long and that NBName has
+ space for 32 chars, so be careful ...
*/
while (pkt_ptr != NULL) {
- for (i = 0;
- i < ((Len > (pkt_ptr -> len)?pkt_ptr -> len:Len) - Offset);
+ for (i = 0;
+ i < ((Len > (pkt_ptr -> len)?pkt_ptr -> len:Len) - Offset);
i++) {
c = pkt_ptr -> data[i + Offset];
switch (RFCNB_Pkt_Type(pkt -> data)) {
- case RFCNB_SESSION_MESSAGE:
+ case RFCNB_SESSION_MESSAGE:
fprintf(fd, "SESSION MESSAGE: Length = %i\n", RFCNB_Pkt_Len(pkt -> data));
- RFCNB_Print_Hex(fd, pkt, RFCNB_Pkt_Hdr_Len,
+ RFCNB_Print_Hex(fd, pkt, RFCNB_Pkt_Hdr_Len,
#ifdef RFCNB_PRINT_DATA
RFCNB_Pkt_Len(pkt -> data) - RFCNB_Pkt_Hdr_Len);
#else
#endif
if (Prot_Print_Routine != 0) { /* Print the rest of the packet */
-
+
Prot_Print_Routine(fd, strcmp(dirn, "sent"), pkt, RFCNB_Pkt_Hdr_Len,
RFCNB_Pkt_Len(pkt -> data) - RFCNB_Pkt_Hdr_Len);
break;
case RFCNB_SESSION_REJ:
- fprintf(fd, "RFCNB SESSION REJECT: Length = %i\n",
+ fprintf(fd, "RFCNB SESSION REJECT: Length = %i\n",
RFCNB_Pkt_Len(pkt -> data));
if (RFCNB_Pkt_Len(pkt -> data) < 1) {
RFCNB_errno = RFCNBE_BadSocket;
RFCNB_saved_errno = errno;
return(RFCNBE_Bad);
- }
+ }
bzero((char *)&Socket, sizeof(Socket));
memcpy((char *)&Socket.sin_addr, (char *)&Dest_IP, sizeof(Dest_IP));
}
-/* handle the details of establishing the RFCNB session with remote
- end
+/* handle the details of establishing the RFCNB session with remote
+ end
*/
-int RFCNB_Session_Req(struct RFCNB_Con *con,
- char *Called_Name,
+int RFCNB_Session_Req(struct RFCNB_Con *con,
+ char *Called_Name,
char *Calling_Name,
BOOL *redirect,
struct in_addr *Dest_IP,
#ifdef RFCNB_DEBUG
fprintf(stderr, "Sending packet: ");
-
+
#endif
if ((len = RFCNB_Put_Pkt(con, pkt, RFCNB_Pkt_Sess_Len)) < 0) {
case RFCNB_SESSION_REJ: /* Didnt like us ... too bad */
/* Why did we get rejected ? */
-
+
switch (CVAL(resp,RFCNB_Pkt_Error_Offset)) {
- case 0x80:
+ case 0x80:
RFCNB_errno = RFCNBE_CallRejNLOCN;
break;
case 0x81:
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
int RFCNB_IP_Connect(struct in_addr Dest_IP, int port);
-int RFCNB_Session_Req(struct RFCNB_Con *con,
- char *Called_Name,
+int RFCNB_Session_Req(struct RFCNB_Con *con,
+ char *Called_Name,
char *Calling_Name,
BOOL *redirect,
struct in_addr *Dest_IP,
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
static int smb_instantiate(CONF_SECTION *conf, void **instance)
{
rlm_smb_t *data;
-
+
/*
* Set up a storage area for instance data
*/
free(data);
return -1;
}
-
+
*instance = data;
-
+
return 0;
}
case 2: /* protocol failure */
return RLM_MODULE_FAIL;
break;
-
+
case 3: /* invalid user name or password */
return RLM_MODULE_REJECT;
}
* is single-threaded.
*/
module_t rlm_smb = {
- "SMB",
+ "SMB",
RLM_TYPE_THREAD_UNSAFE, /* type */
NULL, /* initialization */
smb_instantiate, /* instantiation */
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
/* Set up a session with a remote name. We are passed Called_Name as a
string which we convert to a NetBIOS name, ie space terminated, up to
16 characters only if we need to. If Called_Address is not empty, then
- we use it to connect to the remote end, but put in Called_Name ... Called
+ we use it to connect to the remote end, but put in Called_Name ... Called
Address can be a DNS based name, or a TCP/IP address ...
*/
return(NULL);
}
-
+
con -> fd = -0; /* no descriptor yet */
con -> rfc_errno = 0; /* no error yet */
con -> timeout = 0; /* no timeout */
/* And tack it onto the list of addresses we called */
if ((redir_addr = (struct redirect_addr *)malloc(sizeof(struct redirect_addr))) == NULL) { /* Could not get space */
-
+
RFCNB_errno = RFCNBE_NoSpace;
RFCNB_saved_errno = errno;
return(NULL);
con -> fd = Client;
/* Now send and handle the RFCNB session request */
- /* If we get a redirect, we will comeback with redirect true
+ /* If we get a redirect, we will comeback with redirect true
and a new IP address in DEST_IP */
- if ((errno = RFCNB_Session_Req(con,
+ if ((errno = RFCNB_Session_Req(con,
Called_Name,
Calling_Name,
&redirect, &Dest_IP, &port)) < 0) {
}
-/* We send a packet to the other end ... for the moment, we treat the
+/* We send a packet to the other end ... for the moment, we treat the
data as a series of pointers to blocks of data ... we should check the
length ... */
#ifdef RFCNB_DEBUG
fprintf(stderr, "Sending packet: ");
-
+
#endif
if ((len = RFCNB_Put_Pkt(Con_Handle, pkt, Length + RFCNB_Pkt_Hdr_Len)) < 0) {
/* No need to change RFCNB_errno as it was done by put_pkt ... */
return(RFCNBE_Bad); /* Should be able to write that lot ... */
-
+
}
/* Now we have sent that lot, let's get rid of the RFCNB Header and return */
}
-/* We pick up a message from the internet ... We have to worry about
+/* We pick up a message from the internet ... We have to worry about
non-message packets ... */
int RFCNB_Recv(void *con_Handle, struct RFCNB_Pkt *Data, int Length)
{
- return(setsockopt(con_Handle -> fd, IPPROTO_TCP, TCP_NODELAY,
+ return(setsockopt(con_Handle -> fd, IPPROTO_TCP, TCP_NODELAY,
(char *)&yn, sizeof(yn)));
}
-/*
+/*
Unix SMB/Netbios implementation.
Version 1.9.
- a partial implementation of DES designed for use in the
+ a partial implementation of DES designed for use in the
SMB authentication protocol
Copyright (C) Andrew Tridgell 1997
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* NOTES:
+/* NOTES:
This code makes no attempt to be fast! In fact, it is a very
- slow implementation
+ slow implementation
This code is NOT a complete DES implementation. It implements only
the minimum necessary for SMB authentication, as used by all SMB
lshift(c, sc[i], 28);
lshift(d, sc[i], 28);
- concat(cd, c, d, 28, 28);
- permute(ki[i], cd, perm2, 48);
+ concat(cd, c, d, 28, 28);
+ permute(ki[i], cd, perm2, 48);
}
permute(pd1, in, perm3, 64);
int m, n;
m = (b[j][0]<<1) | b[j][5];
- n = (b[j][1]<<3) | (b[j][2]<<2) | (b[j][3]<<1) | b[j][4];
+ n = (b[j][1]<<3) | (b[j][2]<<2) | (b[j][3]<<1) | b[j][4];
- for (k=0;k<4;k++)
- b[j][k] = (sbox[j][m][n] & (1<<(3-k)))?1:0;
+ for (k=0;k<4;k++)
+ b[j][k] = (sbox[j][m][n] & (1<<(3-k)))?1:0;
}
for (j=0;j<8;j++)
-/*
+/*
Unix SMB/Netbios implementation.
Version 1.9.
SMB parameters and setup
Copyright (C) Andrew Tridgell 1992-1997
Modified by Jeremy Allison 1995.
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
/*
This implements the X/Open SMB password encryption
- It takes a password, a 8 byte "crypt key" and puts 24 bytes of
+ It takes a password, a 8 byte "crypt key" and puts 24 bytes of
encrypted password into p24 */
void SMBencrypt(uchar *passwd, uchar *c8, uchar *p24)
{
StrnCpy((char *)p14,(char *)passwd,14);
strupper((char *)p14);
- E_P16(p14, p21);
+ E_P16(p14, p21);
E_P24(p21, c8, p24);
}
/*
* Convert a string into an NT UNICODE string.
- * Note that regardless of processor type
+ * Note that regardless of processor type
* this must be in intel (little-endian)
* format.
*/
-
+
static int _my_mbstowcs(int16 *dst, uchar *src, int len)
{
int i;
int16 val;
-
+
for(i = 0; i < len; i++) {
val = *src;
SSVAL(dst,0,val);
return i;
}
-/*
+/*
* Creates the MD4 Hash of the users password in NT UNICODE.
*/
-
+
void E_md4hash(uchar *passwd, uchar *p16)
{
int len;
int16 wpwd[129];
-
+
/* Password cannot be longer than 128 characters */
len = strlen((char *)passwd);
if(len > 128)
}
/* Does the NT MD4 hash then des encryption. */
-
+
void SMBNTencrypt(uchar *passwd, uchar *c8, uchar *p24)
{
uchar p21[21];
-
+
memset(p21,'\0',21);
-
- E_md4hash(passwd, p21);
+
+ E_md4hash(passwd, p21);
E_P24(p21, c8, p24);
}
#if !defined(KANJI_WIN95_COMPATIBILITY)
if(lp_client_code_page() == KANJI_CODEPAGE)
{
-
+
if (is_shift_jis (*s))
{
if (is_sj_lower (s[0], s[1]))
}
else
{
- if (islower(*s))
+ if (islower(*s))
*s = toupper(*s);
s++;
}
s++;
}
}
-}
+}
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#define SMB_P_CorePlus 1
#define SMB_P_DOSLanMan1 2
#define SMB_P_LanMan1 3
-#define SMB_P_DOSLanMan2 4
+#define SMB_P_DOSLanMan2 4
#define SMB_P_LanMan2 5
#define SMB_P_DOSLanMan2_1 6
#define SMB_P_LanMan2_1 7
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#define max(a,b) (a < b ? b : a)
#define SMB_DEF_IDF 0x424D53FF /* "\377SMB" */
-
+
/* Core protocol commands */
#define SMBmkdir 0x00 /* create directory */
#define SMB_tconr_mbs_offset 33 /* max buffer size */
#define SMB_tconr_tid_offset 35 /* returned tree id */
-#define SMB_tconr_bcc_offset 37
-#define SMB_tconr_len 39
+#define SMB_tconr_bcc_offset 37
+#define SMB_tconr_len 39
#define SMB_tconx_axc_offset 33 /* And X Command */
#define SMB_tconx_axr_offset 34 /* reserved */
#define SMB_clos_fid_offset 33 /* FID to close */
#define SMB_clos_tim_offset 35 /* Last mod time */
-#define SMB_clos_bcc_offset 39 /* bcc */
+#define SMB_clos_bcc_offset 39 /* bcc */
#define SMB_clos_len 41
/* Offsets related to Write requests */
#define SMB_LMapi_SetUserInfo 0x0072
#define SMB_LMapi_UserPasswordSet 0x0073
-
+
/* Structures and defines we use in the client interface */
/* The protocols we might support. Perhaps a bit ambitious, as only RFCNB */
/* We must make it possible for callers to specify these ... */
-static const char *SMB_Prots[] = {"PC NETWORK PROGRAM 1.0",
+static const char *SMB_Prots[] = {"PC NETWORK PROGRAM 1.0",
"MICROSOFT NETWORKS 1.03",
"MICROSOFT NETWORKS 3.0",
"DOS LANMAN1.0",
int max_xmit; /* Max xmit permitted by server */
int Security; /* 0 = share, 1 = user */
int Raw_Support; /* bit 0 = 1 = Read Raw supported, 1 = 1 Write raw */
- BOOL encrypt_passwords; /* FALSE = don't */
+ BOOL encrypt_passwords; /* FALSE = don't */
int MaxMPX, MaxVC, MaxRaw;
unsigned int SessionKey, Capabilities;
int SvrTZ; /* Server Time Zone */
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
SMB_Time_Temp[0] = 0;
DOS_sec = (DOS_time & 0x001F) * 2;
- DOS_min = (DOS_time & 0x07E0) >> 5;
+ DOS_min = (DOS_time & 0x07E0) >> 5;
DOS_hour = ((DOS_time & 0xF800) >> 11);
DOS_day = (DOS_time & 0x001F0000) >> 16;
}
/* Convert an attribute byte/word etc to a string ... We return a pointer
- to a static string which we guarantee is long enough. If verbose is
+ to a static string which we guarantee is long enough. If verbose is
true, we print out long form of strings ... */
char *SMB_AtrToStr(int attribs, BOOL verbose)
SMB_Attrib_Temp[0] = 0;
- if (attribs & SMB_FA_ROF)
+ if (attribs & SMB_FA_ROF)
strcat(SMB_Attrib_Temp, (verbose?"Read Only ":"R"));
- if (attribs & SMB_FA_HID)
+ if (attribs & SMB_FA_HID)
strcat(SMB_Attrib_Temp, (verbose?"Hidden ":"H"));
- if (attribs & SMB_FA_SYS)
+ if (attribs & SMB_FA_SYS)
strcat(SMB_Attrib_Temp, (verbose?"System ":"S"));
- if (attribs & SMB_FA_VOL)
+ if (attribs & SMB_FA_VOL)
strcat(SMB_Attrib_Temp, (verbose?"Volume ":"V"));
- if (attribs & SMB_FA_DIR)
+ if (attribs & SMB_FA_DIR)
strcat(SMB_Attrib_Temp, (verbose?"Directory ":"D"));
- if (attribs & SMB_FA_ARC)
+ if (attribs & SMB_FA_ARC)
strcat(SMB_Attrib_Temp, (verbose?"Archive ":"A"));
return(SMB_Attrib_Temp);
return(SMBlibE_BAD);
}
-
+
if (SVAL(SMB_Hdr(pkt), SMB_negrCP_idx_offset) == 0xFFFF) {
#ifdef DEBUG
return(SMBlibE_BAD);
}
-
+
switch (CVAL(SMB_Hdr(pkt), SMB_hdr_wct_offset)) {
case 0x01: /* No more info ... */
Con_Handle -> SessionKey = IVAL(SMB_Hdr(pkt), SMB_negrLM_sk_offset);
Con_Handle -> SvrTZ = SVAL(SMB_Hdr(pkt), SMB_negrLM_stz_offset);
Con_Handle -> Encrypt_Key_Len = SVAL(SMB_Hdr(pkt), SMB_negrLM_ekl_offset);
-
+
p = (SMB_Hdr(pkt) + SMB_negrLM_buf_offset);
fprintf(stderr, "%d", (char *)(SMB_Hdr(pkt) + SMB_negrLM_buf_offset));
memcpy(Con_Handle->Encrypt_Key, p, 8);
/* Send a TCON to the remote server ... */
-SMB_Tree_Handle SMB_TreeConnect(SMB_Handle_Type Con_Handle,
+SMB_Tree_Handle SMB_TreeConnect(SMB_Handle_Type Con_Handle,
SMB_Tree_Handle Tree_Handle,
- char *path,
+ char *path,
char *password,
char *device)
tree = (SMB_Tree_Handle)malloc(sizeof(struct SMB_Tree_Structure));
if (tree == NULL) {
-
+
RFCNB_Free_Pkt(pkt);
SMBlib_errno = SMBlibE_NoSpace;
return(NULL);
-
+
}
}
else {
fprintf(stderr, "Error receiving response to TCon\n");
#endif
- if (Tree_Handle == NULL)
+ if (Tree_Handle == NULL)
free(tree);
RFCNB_Free_Pkt(pkt);
SMBlib_errno = -SMBlibE_RecvFailed;
}
RFCNB_Free_Pkt(pkt);
- return(tree);
+ return(tree);
}
if (msg >= 0) {
- strncpy(msgbuf,
+ strncpy(msgbuf,
SMBlib_Error_Messages[msg>SMBlibE_NoSuchMsg?SMBlibE_NoSuchMsg:msg],
len - 1);
msgbuf[len - 1] = 0; /* Make sure it is a string */
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
strcpy(con -> PDomain, NTdomain);
strcpy(con -> OSName, SMBLIB_DEFAULT_OSNAME);
strcpy(con -> LMType, SMBLIB_DEFAULT_LMTYPE);
- con -> first_tree = con -> last_tree = NULL;
+ con -> first_tree = con -> last_tree = NULL;
SMB_Get_My_Name(con -> myname, sizeof(con -> myname));
con -> pid = getpid();
con -> mid = con -> pid; /* This will do for now ... */
- con -> uid = 0; /* Until we have done a logon, no uid ... */
+ con -> uid = 0; /* Until we have done a logon, no uid ... */
con -> gid = getgid();
/* Now connect to the remote end, but first upper case the name of the
for (i=0; i < strlen(server); i++)
called[i] = toupper(server[i]);
-
+
called[strlen(server)] = 0; /* Make it a string */
for (i=0; i < strlen(con -> myname); i++)
calling[i] = toupper(con -> myname[i]);
-
+
calling[strlen(con -> myname)] = 0; /* Make it a string */
if (strcmp(con -> address, "") == 0)
SMB_Handle_Type SMB_Connect(SMB_Handle_Type Con_Handle,
SMB_Tree_Handle *tree,
- char *service,
- char *username,
+ char *service,
+ char *username,
char *password)
{ SMB_Handle_Type con;
for (i=0; i < strlen(host); i++)
called[i] = toupper(host[i]);
-
+
called[strlen(host)] = 0; /* Make it a string */
for (i=0; i < strlen(con -> myname); i++)
calling[i] = toupper(con -> myname[i]);
-
+
calling[strlen(con -> myname)] = 0; /* Make it a string */
if (strcmp(con -> address, "") == 0)
/* Logon to the server. That is, do a session setup if we can. We do not do */
/* Unicode yet! */
-int SMB_Logon_Server(SMB_Handle_Type Con_Handle, char *UserName,
+int SMB_Logon_Server(SMB_Handle_Type Con_Handle, char *UserName,
char *PassWord)
{ struct RFCNB_Pkt *pkt;
if (Con_Handle -> encrypt_passwords)
{
pass_len=24;
- SMBencrypt((uchar *) PassWord, (uchar *)Con_Handle -> Encrypt_Key,(uchar *)pword);
- }
- else
+ SMBencrypt((uchar *) PassWord, (uchar *)Con_Handle -> Encrypt_Key,(uchar *)pword);
+ }
+ else
pass_len=strlen(pword);
if (Con_Handle -> protocol < SMB_P_NT1) {
- param_len = strlen(UserName) + 1 + pass_len + 1 +
- strlen(Con_Handle -> PDomain) + 1 +
+ param_len = strlen(UserName) + 1 + pass_len + 1 +
+ strlen(Con_Handle -> PDomain) + 1 +
strlen(Con_Handle -> OSName) + 1;
pkt_len = SMB_ssetpLM_len + param_len;
/* We don't admit to UNICODE support ... */
- param_len = strlen(UserName) + 1 + pass_len +
- strlen(Con_Handle -> PDomain) + 1 +
+ param_len = strlen(UserName) + 1 + pass_len +
+ strlen(Con_Handle -> PDomain) + 1 +
strlen(Con_Handle -> OSName) + 1 +
strlen(Con_Handle -> LMType) + 1;
{
/* do we allow guest login? NO! */
return(SMBlibE_BAD);
-
+
}
/** @@@ mdz: } **/
#ifdef DEBUG
- fprintf(stderr, "SessSetupAndX response. Action = %i\n",
+ fprintf(stderr, "SessSetupAndX response. Action = %i\n",
SVAL(SMB_Hdr(pkt), SMB_ssetpr_act_offset));
#endif
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
/* Connect to a server and give us back a handle. If Con == NULL, create */
/* The handle and populate it with defaults */
-void *SMB_Connect(void *Con, void **tree,
+void *SMB_Connect(void *Con, void **tree,
char *name, char *User, char *Password);
/* Negotiate a protocol */
/* Connect to a tree ... */
-void *SMB_TreeConnect(void *con_handle, void *tree_handle,
+void *SMB_TreeConnect(void *con_handle, void *tree_handle,
char *path, char *password, char *dev);
/* Disconnect a tree ... */
void *file_handle,
char *file_name,
unsigned short mode,
- unsigned short search);
+ unsigned short search);
/* Close a file */
int SMB_Discon(void *Con, BOOL KeepHandle);
void *SMB_Create(void *Tree_Handle,
- void *File_Handle,
- char *file_name,
+ void *File_Handle,
+ char *file_name,
short search);
int SMB_Delete(void *tree, char *file_name, short search);
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
if (con == NULL) { /* Error ... */
con = SMB_Connect_Server(NULL, BACKUP, DOMAIN);
if (con == NULL) {
- return(NTV_SERVER_ERROR);
+ return(NTV_SERVER_ERROR);
}
}
if (SMB_Negotiate(con, SMB_Prots) < 0) { /* An error */
SMB_Discon(con,0);
return(NTV_LOGON_ERROR);
}
-
+
SMB_Discon(con,0);
return(NTV_NO_ERROR);
}
* Copyright 2001 Joerg Wendland <wendland@scan-plus.de>
*/
-/*
- * Modification of rlm_sql_db2 to handle IBM DB2 UDB V7
+/*
+ * Modification of rlm_sql_db2 to handle IBM DB2 UDB V7
* by Joerg Wendland <wendland@scan-plus.de>
*/
}
-/*************************************************************************
- *
- * Function: sql_destroy_socket
- *
- * Purpose: Free socket and private connection data
- *
+/*************************************************************************
+ *
+ * Function: sql_destroy_socket
+ *
+ * Purpose: Free socket and private connection data
+ *
*************************************************************************/
static int sql_destroy_socket(SQLSOCK *sqlsocket, SQL_CONFIG *config)
{
* Purpose: Issue a query to the database
*
*************************************************************************/
-static int sql_query(SQLSOCK * sqlsocket, SQL_CONFIG *config, char *querystr)
+static int sql_query(SQLSOCK * sqlsocket, SQL_CONFIG *config, char *querystr)
{
SQLRETURN retval;
rlm_sql_db2_sock *sock;
radlog(L_DBG,"query:\n%s", querystr);
/* allocate handle for statement */
- SQLAllocHandle(SQL_HANDLE_STMT, sock->hdbc,
+ SQLAllocHandle(SQL_HANDLE_STMT, sock->hdbc,
&(sock->stmt));
/* execute query */
* Purpose: Issue a select query to the database
*
*************************************************************************/
-static int sql_select_query(SQLSOCK * sqlsocket, SQL_CONFIG *config, char *querystr)
+static int sql_select_query(SQLSOCK * sqlsocket, SQL_CONFIG *config, char *querystr)
{
return sql_query(sqlsocket, config, querystr);
}
* set for the query.
*
*************************************************************************/
-static int sql_store_result(SQLSOCK * sqlsocket, SQL_CONFIG *config)
+static int sql_store_result(SQLSOCK * sqlsocket, SQL_CONFIG *config)
{
return 0;
}
* of columns from query
*
*************************************************************************/
-static int sql_num_fields(SQLSOCK * sqlsocket, SQL_CONFIG *config)
+static int sql_num_fields(SQLSOCK * sqlsocket, SQL_CONFIG *config)
{
SQLSMALLINT c;
rlm_sql_db2_sock *sock;
* 0 on success, -1 on failure, SQL_DOWN if 'database is down'
*
*************************************************************************/
-static int sql_fetch_row(SQLSOCK * sqlsocket, SQL_CONFIG *config)
+static int sql_fetch_row(SQLSOCK * sqlsocket, SQL_CONFIG *config)
{
int c, i;
SQLINTEGER len, slen;
* for a result set
*
*************************************************************************/
-static int sql_free_result(SQLSOCK * sqlsocket, SQL_CONFIG *config)
+static int sql_free_result(SQLSOCK * sqlsocket, SQL_CONFIG *config)
{
rlm_sql_db2_sock *sock;
sock = sqlsocket->conn;
* connection
*
*************************************************************************/
-static char *sql_error(SQLSOCK * sqlsocket, SQL_CONFIG *config)
+static char *sql_error(SQLSOCK * sqlsocket, SQL_CONFIG *config)
{
/* this should really be enough, if not, you still got the sqlstate */
#define MSGLEN 512
* connection
*
*************************************************************************/
-static int sql_close(SQLSOCK * sqlsocket, SQL_CONFIG *config)
+static int sql_close(SQLSOCK * sqlsocket, SQL_CONFIG *config)
{
rlm_sql_db2_sock *sock;
* Purpose: End the query, such as freeing memory
*
*************************************************************************/
-static int sql_finish_query(SQLSOCK * sqlsocket, SQL_CONFIG *config)
+static int sql_finish_query(SQLSOCK * sqlsocket, SQL_CONFIG *config)
{
return 0;
}
* Purpose: End the select query, such as freeing memory or result
*
*************************************************************************/
-static int sql_finish_select_query(SQLSOCK * sqlsocket, SQL_CONFIG *config)
+static int sql_finish_select_query(SQLSOCK * sqlsocket, SQL_CONFIG *config)
{
return sql_finish_query(sqlsocket, config);
}
* Purpose: Return the number of rows affected by the last query.
*
*************************************************************************/
-static int sql_affected_rows(SQLSOCK * sqlsocket, SQL_CONFIG *config)
+static int sql_affected_rows(SQLSOCK * sqlsocket, SQL_CONFIG *config)
{
SQLINTEGER c;
rlm_sql_db2_sock *sock;
HSTMT stmt_handle;
int id;
SQL_ROW row;
-
+
struct sql_socket *next;
void *conn;
memset(iodbc_sock, 0, sizeof(*iodbc_sock));
if(SQLAllocEnv(&iodbc_sock->env_handle) != SQL_SUCCESS) {
- radlog(L_CONS|L_ERR, "sql_create_socket: SQLAllocEnv failed: %s",
+ radlog(L_CONS|L_ERR, "sql_create_socket: SQLAllocEnv failed: %s",
sql_error(sqlsocket, config));
return -1;
}
if(SQLAllocConnect(iodbc_sock->env_handle, &iodbc_sock->dbc_handle) != SQL_SUCCESS) {
- radlog(L_CONS|L_ERR, "sql_create_socket: SQLAllocConnect failed: %s",
+ radlog(L_CONS|L_ERR, "sql_create_socket: SQLAllocConnect failed: %s",
sql_error(sqlsocket, config));
return -1;
}
- if (SQLConnect(iodbc_sock->dbc_handle, config->sql_db, SQL_NTS,
- config->sql_login, SQL_NTS, config->sql_password,
+ if (SQLConnect(iodbc_sock->dbc_handle, config->sql_db, SQL_NTS,
+ config->sql_login, SQL_NTS, config->sql_password,
SQL_NTS) != SQL_SUCCESS) {
- radlog(L_CONS|L_ERR, "sql_create_socket: SQLConnectfailed: %s",
+ radlog(L_CONS|L_ERR, "sql_create_socket: SQLConnectfailed: %s",
sql_error(sqlsocket, config));
return -1;
}
rlm_sql_iodbc_sock *iodbc_sock = sqlsocket->conn;
if(SQLAllocStmt(iodbc_sock->dbc_handle, &iodbc_sock->stmt_handle) != SQL_SUCCESS) {
- radlog(L_CONS|L_ERR, "sql_create_socket: SQLAllocStmt failed: %s",
+ radlog(L_CONS|L_ERR, "sql_create_socket: SQLAllocStmt failed: %s",
sql_error(sqlsocket, config));
return -1;
}
rlm_sql_iodbc_sock *iodbc_sock = sqlsocket->conn;
if(sql_query(sqlsocket, config, querystr) < 0) {
- return -1;
+ return -1;
}
numfields = sql_num_fields(sqlsocket, config);
row = (char **) rad_malloc(sizeof(char *) * (numfields+1));
- memset(row, 0, (sizeof(char *) * (numfields)));
+ memset(row, 0, (sizeof(char *) * (numfields)));
row[numfields] = NULL;
for(i=1; i<=numfields; i++) {
NULL, 0, NULL, &len);
len++;
- /*
- * Allocate space for each column
+ /*
+ * Allocate space for each column
*/
row[i-1] = (SQLCHAR*)rad_malloc((int)len);
return 0;
}
/* XXX Check rc for database down, if so, return SQL_DOWN */
-
+
sqlsocket->row = iodbc_sock->row;
return 0;
}
static SQLCHAR error[256] = "";
rlm_sql_iodbc_sock *iodbc_sock = sqlsocket->conn;
- SQLError(iodbc_sock->env_handle, iodbc_sock->dbc_handle, iodbc_sock->stmt_handle,
+ SQLError(iodbc_sock->env_handle, iodbc_sock->dbc_handle, iodbc_sock->stmt_handle,
state, &errornum, error, 256, &length);
return error;
}
static char msgbuf[512];
sb4 errcode = 0;
rlm_sql_oracle_sock *oracle_sock = sqlsocket->conn;
-
+
memset((void *) msgbuf, (int)'\0', sizeof(msgbuf));
OCIErrorGet((dvoid *) oracle_sock->errHandle, (ub4) 1, (text *) NULL,
*
*************************************************************************/
static int sql_init_socket(SQLSOCK *sqlsocket, SQL_CONFIG *config) {
-
+
rlm_sql_oracle_sock *oracle_sock;
if (!sqlsocket->conn) {
if (OCIEnvCreate(&oracle_sock->env, OCI_DEFAULT|OCI_THREADED, (dvoid *)0,
(dvoid * (*)(dvoid *, size_t)) 0,
- (dvoid * (*)(dvoid *, dvoid *, size_t))0,
+ (dvoid * (*)(dvoid *, dvoid *, size_t))0,
(void (*)(dvoid *, dvoid *)) 0,
0, (dvoid **)0 )) {
radlog(L_ERR,"rlm_sql_oracle: Couldn't init Oracle OCI environment (OCIEnvCreate())");
ub4 count;
rlm_sql_oracle_sock *oracle_sock = sqlsocket->conn;
- /* get the number of columns in the select list */
+ /* get the number of columns in the select list */
if (OCIAttrGet ((dvoid *)oracle_sock->queryHandle,
(ub4)OCI_HTYPE_STMT,
(dvoid *) &count,
return -1;
}
- x=OCIAttrGet((dvoid*)param, OCI_DTYPE_PARAM,
+ x=OCIAttrGet((dvoid*)param, OCI_DTYPE_PARAM,
(dvoid*)&dtype, (ub4*)0, OCI_ATTR_DATA_TYPE,
oracle_sock->errHandle);
if (x != OCI_SUCCESS) {
OCIAttrGet((CONST dvoid *)oracle_sock->queryHandle,
OCI_HTYPE_STMT,
- (dvoid *)&rows,
+ (dvoid *)&rows,
(ub4 *) sizeof(ub4),
OCI_ATTR_ROW_COUNT,
oracle_sock->errHandle);
0,
OCI_FETCH_NEXT,
OCI_DEFAULT);
-
+
num_fields = sql_num_fields(sqlsocket, config);
if (num_fields >= 0) {
for(x=0; x < num_fields; x++) {
}
pg_sock->result = PQexec(pg_sock->conn, querystr);
- /* Returns a result pointer or possibly a NULL pointer.
+ /* Returns a result pointer or possibly a NULL pointer.
* A non-NULL pointer will generally be returned except in
* out-of-memory conditions or serious errors such as inability
* to send the command to the backend. If a NULL is returned,
*/
if (!pg_sock->result)
{
- radlog(L_ERR, "rlm_sql_postgresql: PostgreSQL Query failed Error: %s",
+ radlog(L_ERR, "rlm_sql_postgresql: PostgreSQL Query failed Error: %s",
PQerrorMessage(pg_sock->conn));
return SQL_DOWN;
} else {
*
*************************************************************************/
static int sql_init_socket(SQLSOCK *sqlsocket, SQL_CONFIG *config) {
-
+
rlm_sql_sybase_sock *sybase_sock;
}
return -1;
}
-
+
/* Allocate a ctlib connection structure */
if (ct_con_alloc(sybase_sock->context, &sybase_sock->connection) != CS_SUCCEED) {
cs_ctx_drop(sybase_sock->context);
}
return -1;
- }
+ }
/* Initialize inline error handling for the connection */
-
+
/* if (ct_diag(sybase_sock->connection, CS_INIT, CS_UNUSED, CS_UNUSED, NULL) != CS_SUCCEED) {
radlog(L_ERR,"rlm_sql_sybase(sql_init_socket): Unable to initialize error handling (ct_diag())");
if (sybase_sock->context != (CS_CONTEXT *)NULL) {
return -1;
}
- if (ct_con_props(sybase_sock->connection, CS_SET, CS_PASSWORD, config->sql_password,
+ if (ct_con_props(sybase_sock->connection, CS_SET, CS_PASSWORD, config->sql_password,
strlen(config->sql_password), NULL) != CS_SUCCEED) {
radlog(L_ERR,"rlm_sql_sybase(sql_init_socket): Unable to set password for connection (ct_con_props())\n%s",
sql_error(sqlsocket, config));
sql_error(sqlsocket, config));
return -1;
}
-
+
if (ct_send(sybase_sock->command) != CS_SUCCEED) {
radlog(L_ERR,"rlm_sql_sybase(sql_query): Unable to send command (ct_send())\n%s",
sql_error(sqlsocket, config));
** we need returncode CS_SUCCEED
** and result_type CS_CMD_SUCCEED.
*/
-
+
if ((results_ret = ct_results(sybase_sock->command, &result_type)) == CS_SUCCEED) {
if (result_type != CS_CMD_SUCCEED) {
if (result_type == CS_ROW_RESULT) {
sql_error(sqlsocket, config));
return -1;
}
- }
+ }
else {
switch ((int) results_ret)
{
** we need returncode CS_SUCCEED
** and result_type CS_CMD_DONE.
*/
-
+
if ((results_ret = ct_results(sybase_sock->command, &result_type)) == CS_SUCCEED) {
if (result_type != CS_CMD_DONE) {
radlog(L_ERR,"rlm_sql_sybase(sql_query): Result failure or unexpected result type from query\n%s",
sql_error(sqlsocket, config));
return -1;
}
- }
+ }
else {
switch ((int) results_ret)
{
** we need returncode CS_END_RESULTS
** result_type will be ignored.
*/
-
+
results_ret = ct_results(sybase_sock->command, &result_type);
switch ((int) results_ret)
*
* Purpose: Issue a select query to the database
*
- * Note: Only the first row from queries returning several rows
+ * Note: Only the first row from queries returning several rows
* will be returned by this function, consequitive rows will
* be discarded.
*
*************************************************************************/
static int sql_select_query(SQLSOCK *sqlsocket, SQL_CONFIG *config, char *querystr) {
-
+
rlm_sql_sybase_sock *sybase_sock = sqlsocket->conn;
CS_RETCODE ret, results_ret;
radlog(L_ERR, "Socket not connected");
return -1;
}
-
+
if (ct_cmd_alloc(sybase_sock->connection, &sybase_sock->command) != CS_SUCCEED) {
radlog(L_ERR,"rlm_sql_sybase(sql_select_query): Unable to allocate command structure (ct_cmd_alloc())\n%s",
sql_error(sqlsocket, config));
return -1;
}
-
+
if (ct_send(sybase_sock->command) != CS_SUCCEED) {
radlog(L_ERR,"rlm_sql_sybase(sql_select_query): Unable to send command (ct_send())\n%s",
sql_error(sqlsocket, config));
case CS_SUCCEED:
- switch (result_type) {
+ switch (result_type) {
case CS_ROW_RESULT:
/*
** Set up the DATAFMT structure that describes our target array
** and tells sybase what we want future ct_fetch calls to do.
- */
+ */
descriptor.datatype = CS_CHAR_TYPE; /* The target buffer is a string */
- descriptor.format = CS_FMT_NULLTERM; /* Null termination please */
+ descriptor.format = CS_FMT_NULLTERM; /* Null termination please */
descriptor.maxlength = MAX_DATASTR_LEN; /* The string arrays are this large */
descriptor.count = 1; /* Fetch one row of data */
descriptor.locale = NULL; /* Don't do NLS stuff */
for (i=0; i < colcount; i++) {
rowdata[i]=rad_malloc((MAX_DATASTR_LEN * sizeof(char))+1); /* Space to hold the result data */
-
+
/* Associate the target buffer with the data */
if (ct_bind(sybase_sock->command, i+1, &descriptor, rowdata[i], NULL, NULL) != CS_SUCCEED) {
radlog(L_ERR,"rlm_sql_sybase(sql_select_query): ct_bind() failed)\n%s",
break;
}
break;
-
- case CS_FAIL:
+
+ case CS_FAIL:
/*
** Serious failure, sybase requires us to cancel
break;
default:
-
+
radlog(L_ERR,"rlm_sql_sybase(sql_select_query): Unexpected return value from ct_results()\n%s",
sql_error(sqlsocket, config));
return -1;
*
*************************************************************************/
static int sql_store_result(SQLSOCK *sqlsocket, SQL_CONFIG *config) {
- /*
+ /*
** Not needed for Sybase, code that may have gone here is
** in sql_select_query and sql_fetch_row
*/
*
*************************************************************************/
static int sql_num_fields(SQLSOCK *sqlsocket, SQL_CONFIG *config) {
-
+
rlm_sql_sybase_sock *sybase_sock = sqlsocket->conn;
int num;
break;
case CS_ROW_FAIL:
-
+
radlog(L_ERR,"rlm_sql_sybase(sql_fetch_row): Recoverable failure fething row data, try again perhaps?");
return -1;
default:
-
+
radlog(L_ERR,"rlm_sql_sybase(sql_fetch_row): Unexpected returncode from ct_fetch");
return -1;
break;
/*
** Not implemented, never called from rlm_sql anyway
** result buffer is freed in the finish_query functions.
- */
+ */
return 0;
cmsg.msgstring);
}
-
+
if (ct_diag(sybase_sock->connection, CS_STATUS, CS_SERVERMSG_TYPE, CS_UNUSED, &msgcount) != CS_SUCCEED) {
radlog(L_ERR,"rlm_sql_sybase(sql_error): Failed to get number of pending Server messages");
return msgbuf;
return msgbuf;
*/
- return &msg;
+ return &msg;
}
*
*************************************************************************/
static int sql_finish_select_query(SQLSOCK *sqlsocket, SQL_CONFIG *config) {
-
+
rlm_sql_sybase_sock *sybase_sock = sqlsocket->conn;
int i=0;
free(sybase_sock->results);
sybase_sock->results=NULL;
}
-
+
return 0;
}
#include <sqlext.h>
/* Forward declarations */
-static char *sql_error(SQLSOCK *sqlsocket, SQL_CONFIG *config);
-static int sql_free_result(SQLSOCK *sqlsocket, SQL_CONFIG *config);
-static int sql_affected_rows(SQLSOCK *sqlsocket, SQL_CONFIG *config);
-static int sql_num_fields(SQLSOCK *sqlsocket, SQL_CONFIG *config);
+static char *sql_error(SQLSOCK *sqlsocket, SQL_CONFIG *config);
+static int sql_free_result(SQLSOCK *sqlsocket, SQL_CONFIG *config);
+static int sql_affected_rows(SQLSOCK *sqlsocket, SQL_CONFIG *config);
+static int sql_num_fields(SQLSOCK *sqlsocket, SQL_CONFIG *config);
/*************************************************************************
static int sql_init_socket(SQLSOCK *sqlsocket, SQL_CONFIG *config) {
rlm_sql_unixodbc_sock *unixodbc_sock;
long err_handle;
-
+
if (!sqlsocket->conn) {
sqlsocket->conn = (rlm_sql_unixodbc_sock *)rad_malloc(sizeof(rlm_sql_unixodbc_sock));
if (!sqlsocket->conn) {
}
unixodbc_sock = sqlsocket->conn;
memset(unixodbc_sock, 0, sizeof(*unixodbc_sock));
-
+
/* 1. Allocate environment handle and register version */
err_handle = SQLAllocHandle(SQL_HANDLE_ENV,SQL_NULL_HANDLE,&unixodbc_sock->env_handle);
if (!SQL_SUCCEEDED(err_handle))
SQLFreeHandle(SQL_HANDLE_ENV, unixodbc_sock->env_handle);
return -1;
}
-
+
/* 3. Connect to the datasource */
err_handle = SQLConnect(unixodbc_sock->dbc_handle,
(SQLCHAR*) config->sql_server, strlen(config->sql_server),
SQLFreeHandle(SQL_HANDLE_ENV, unixodbc_sock->env_handle);
return -1;
}
-
+
/* 4. Allocate the statement */
err_handle = SQLAllocStmt(unixodbc_sock->dbc_handle, &unixodbc_sock->stmt_handle);
if (!SQL_SUCCEEDED(err_handle))
radlog(L_ERR, "rlm_sql_unixodbc: Can't allocate the statement %s\n", sql_error(sqlsocket, config));
return -1;
}
-
+
return 0;
}
-
-
-/*************************************************************************
- *
- * Function: sql_destroy_socket
- *
- * Purpose: Free socket and private connection data
- *
+
+
+/*************************************************************************
+ *
+ * Function: sql_destroy_socket
+ *
+ * Purpose: Free socket and private connection data
+ *
*************************************************************************/
static int sql_destroy_socket(SQLSOCK *sqlsocket, SQL_CONFIG *config)
{
return 0;
}
-
+
/*************************************************************************
*
* Function: sql_query
static int sql_query(SQLSOCK *sqlsocket, SQL_CONFIG *config, char *querystr) {
rlm_sql_unixodbc_sock *unixodbc_sock = sqlsocket->conn;
long err_handle;
-
+
if (config->sqltrace)
radlog(L_DBG, "query: %s", querystr);
-
+
/* Executing query */
err_handle = SQLExecDirect(unixodbc_sock->stmt_handle, (SQLCHAR *)querystr, strlen(querystr));
if (!SQL_SUCCEEDED(err_handle))
int numfields;
if(sql_query(sqlsocket, config, querystr) < 0)
- return -1;
+ return -1;
numfields=sql_num_fields(sqlsocket, config);
if(numfields < 0)
rlm_sql_unixodbc_sock *unixodbc_sock = sqlsocket->conn;
long err_handle;
int num_fields = 0;
-
+
err_handle = SQLNumResultCols(unixodbc_sock->stmt_handle,(SQLSMALLINT *)&num_fields);
if (!SQL_SUCCEEDED(err_handle))
{
*************************************************************************/
static int sql_close(SQLSOCK *sqlsocket, SQL_CONFIG *config) {
rlm_sql_unixodbc_sock *unixodbc_sock = sqlsocket->conn;
-
+
SQLFreeStmt(unixodbc_sock->stmt_handle, SQL_DROP);
SQLDisconnect(unixodbc_sock->dbc_handle);
SQLFreeConnect(unixodbc_sock->dbc_handle);
SQLINTEGER errornum = 0;
SQLSMALLINT length = 255;
char *result;
-
+
rlm_sql_unixodbc_sock *unixodbc_sock = sqlsocket->conn;
SQLError(
error,
256,
&length);
-
+
result = (char*)rad_malloc(strlen(state)+1+strlen(error));
sprintf(result, "%s %s", state, error);
return result;
static int sql_escape_func(char *out, int outlen, const char *in)
{
int len = 0;
-
+
while (in[0]) {
/*
* Only one byte left.
if (outlen <= 1) {
break;
}
-
+
/*
* Non-printable characters get replaced with their
* mime-encoded equivalents.
len += 3;
continue;
}
-
+
/*
* Else it's a nice character.
*/
if (module_config[i].type != PW_TYPE_STRING_PTR) {
continue;
}
-
+
/*
* Treat 'config' as an opaque array of bytes,
* and take the offset into it. There's a
DEBUG2("rlm_sql: check items");
vp_listdebug(check_tmp);
DEBUG2("rlm_sql: reply items");
- vp_listdebug(reply_tmp);
+ vp_listdebug(reply_tmp);
*/
if (paircmp(request, request->packet->vps, check_tmp, &reply_tmp) != 0) {
switch (acctstatustype) {
/*
* The Terminal server informed us that it was rebooted
- * STOP all records from this NAS
+ * STOP all records from this NAS
*/
case PW_STATUS_ACCOUNTING_ON:
case PW_STATUS_ACCOUNTING_OFF:
(char *)(inst->module->sql_error)(sqlsocket, inst->config));
/*
- * We failed the insert above. It's probably because
+ * We failed the insert above. It's probably because
* the stop record came before the start. We try an
* our alternate query now (typically an UPDATE)
*/
if (*querystr) { /* non-empty query */
if (rlm_sql_query(sqlsocket, inst, querystr)) {
radlog(L_ERR, "rlm_sql (%s): Couldn't update SQL" "accounting START record - %s",
- inst->config->xlat_name,
+ inst->config->xlat_name,
(char *)(inst->module->sql_error)(sqlsocket, inst->config));
ret = RLM_MODULE_FAIL;
}
if (numaffected < 1) {
/*
* If our update above didn't match anything
- * we assume it's because we haven't seen a
+ * we assume it's because we haven't seen a
* matching Start record. So we have to
* insert this stop rather than do an update
*/
*/
if ((pair = pairfind(request->packet->vps, PW_ACCT_SESSION_TIME)) != NULL)
acctsessiontime = pair->lvalue;
-
+
if (acctsessiontime <= 0) {
radius_xlat(logstr, sizeof(logstr), "rlm_sql: Stop packet with zero session length. (user '%{User-Name}', nas '%{NAS-IP-Address}')", request, sql_escape_func);
radlog(L_ERR, logstr);
/*
* See if a user is already logged in. Sets request->simul_count to the
* current session count for this user.
- *
+ *
* Check twice. If on the first pass the user exceeds his
* max. number of logins, do a second pass and validate all
* logins by querying the terminal server (using eg. SNMP).
if ((vp = pairfind(request->packet->vps, PW_FRAMED_IP_ADDRESS)) != NULL)
ipno = vp->lvalue;
if ((vp = pairfind(request->packet->vps, PW_CALLING_STATION_ID)) != NULL)
- call_num = vp->strvalue;
+ call_num = vp->strvalue;
while (rlm_sql_fetch_row(sqlsocket, inst) == 0) {
*
* Function: sql_get_socket
*
- * Purpose: Return a SQL sqlsocket from the connection pool
+ * Purpose: Return a SQL sqlsocket from the connection pool
*
*************************************************************************/
SQLSOCK * sql_get_socket(SQL_INST * inst)
if (unconnected != 0 || tried_to_connect != 0) {
radlog(L_INFO, "rlm_sql (%s): got socket %d after skipping %d unconnected handles, tried to reconnect %d though", inst->config->xlat_name, cur->id, unconnected, tried_to_connect);
}
-
+
/*
* The socket is returned in the locked
* state.
}
/*
- * If we're at the socket we started
+ * If we're at the socket we started
*/
if (cur == start) {
break;
*
* Function: sql_release_socket
*
- * Purpose: Frees a SQL sqlsocket back to the connection pool
+ * Purpose: Frees a SQL sqlsocket back to the connection pool
*
*************************************************************************/
int sql_release_socket(SQL_INST * inst, SQLSOCK * sqlsocket)
if (pairmode <= T_EOL) pairmode = T_OP_CMP_EQ;
/*
- * If attribute is already there, skip it because we checked usercheck first
- * and we want user settings to over ride group settings
+ * If attribute is already there, skip it because we checked usercheck first
+ * and we want user settings to over ride group settings
*/
if (pairmode != T_OP_ADD && (check = pairfind(*first_pair, attr->attr)) != NULL &&
#ifdef ASCEND_BINARY
buffer);
} else {
int fd = fileno(sqlfile);
-
+
rad_lockfd(fd, MAX_QUERY_LEN);
fputs(querystr, sqlfile);
fputs(";\n", sqlfile);
/* Note: When your counter spans more than 1 period (ie 3 months or 2 weeks), this module
- * probably does NOT do what you want! It calculates the range of dates to count across
+ * probably does NOT do what you want! It calculates the range of dates to count across
* by first calculating the End of the Current period and then subtracting the number of
* periods you specify from that to determine the beginning of the range.
*
- * For example, if you specify a 3 month counter and today is June 15th, the end of the current
- * period is June 30. Subtracting 3 months from that gives April 1st. So, the counter will
+ * For example, if you specify a 3 month counter and today is June 15th, the end of the current
+ * period is June 30. Subtracting 3 months from that gives April 1st. So, the counter will
* sum radacct entries from April 1st to June 30. Then, next month, it will sum entries
* from May 1st to July 31st.
*
- * To fix this behavior, we need to add some way of storing the Next Reset Time
+ * To fix this behavior, we need to add some way of storing the Next Reset Time
*/
return -1;
}
strftime(sNextTime, sizeof(sNextTime),"%Y-%m-%d %H:%M:%S",tm);
- DEBUG2("rlm_sqlcounter: Current Time: %d [%s], Next reset %d [%s]",
+ DEBUG2("rlm_sqlcounter: Current Time: %d [%s], Next reset %d [%s]",
(int)timeval,sCurrentTime,(int)data->reset_time, sNextTime);
return ret;
return -1;
}
strftime(sPrevTime, sizeof(sPrevTime),"%Y-%m-%d %H:%M:%S",tm);
- DEBUG2("rlm_sqlcounter: Current Time: %d [%s], Prev reset %d [%s]",
+ DEBUG2("rlm_sqlcounter: Current Time: %d [%s], Prev reset %d [%s]",
(int)timeval,sCurrentTime,(int)data->last_reset, sPrevTime);
return ret;
/*
* 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
+ * a closing brace and apply it
*/
if((c == '}') && openbraces) {
openbraces--;
*q++ = *p;
case 'b': /* last_reset */
sprintf(tmpdt, "%lu", data->last_reset);
- strNcpy(q, tmpdt, freespace);
+ strNcpy(q, tmpdt, freespace);
q += strlen(q);
break;
case 'e': /* reset_time */
sprintf(tmpdt, "%lu", data->reset_time);
- strNcpy(q, tmpdt, freespace);
+ strNcpy(q, tmpdt, freespace);
q += strlen(q);
break;
case 'k': /* Key Name */
- strNcpy(q, data->key_name, freespace);
+ strNcpy(q, data->key_name, freespace);
q += strlen(q);
break;
case 'S': /* SQL module instance */
- strNcpy(q, data->sqlmod_inst, freespace);
+ strNcpy(q, data->sqlmod_inst, freespace);
q += strlen(q);
break;
default:
DICT_ATTR *dattr;
ATTR_FLAGS flags;
time_t now;
-
+
/*
* Set up a storage area for instance data
*/
}
/*
- * Discover the attribute number of the key.
+ * Discover the attribute number of the key.
*/
if (data->key_name == NULL) {
radlog(L_ERR, "rlm_sqlcounter: 'key' must be set.");
return -1;
}
data->key_attr = dattr->attr;
-
+
/*
* Create a new attribute for the counter.
paircompare_register(data->dict_attr, 0, sqlcounter_cmp, data);
*instance = data;
-
+
return 0;
}
snprintf(module_fmsg, sizeof(module_fmsg), "rlm_sqlcounter: Maximum %s usage time reached", data->reset);
module_fmsg_vp = pairmake("Module-Failure-Message", module_fmsg, T_OP_EQ);
- pairadd(&request->packet->vps, module_fmsg_vp);
+ pairadd(&request->packet->vps, module_fmsg_vp);
ret=RLM_MODULE_REJECT;
DEBUG2("rlm_sqlcounter: Rejected user %s, check_item=%d, counter=%d",
- key_vp->strvalue,check_vp->lvalue,counter);
+ key_vp->strvalue,check_vp->lvalue,counter);
}
return ret;
* is single-threaded.
*/
module_t rlm_sqlcounter = {
- "SQL Counter",
+ "SQL Counter",
RLM_TYPE_THREAD_SAFE, /* type */
NULL, /* initialization */
sqlcounter_instantiate, /* instantiation */
/*
- * cache.c Offers ability to cache /etc/group, /etc/passwd,
+ * cache.c Offers ability to cache /etc/group, /etc/passwd,
* /etc/shadow,
*
* All users in the passwd/shadow files are stored in a hash table.
* lookup. For the unitiated, that's blazing. You can't have less
* than one comparison, for example.
*
- * The /etc/group file is stored in a singly linked list, as that
- * appears to be fast enough. It's generally a small enough file
+ * The /etc/group file is stored in a singly linked list, as that
+ * appears to be fast enough. It's generally a small enough file
* that hashing is unnecessary.
*
* Version: $Id$
* Copyright 2000 The FreeRADIUS server project.
* Copyright 1999 Jeff Carneal <jeff@apex.com>, Apex Internet Services, Inc.
* Copyright 2000 Alan DeKok <aland@ox.org>
- */
+ */
static const char rcsid[] = "$Id$";
#include "autoconf.h"
while(fgets(buffer, BUFSIZE , passwd) != (char *)NULL) {
numread++;
-
+
bufptr = buffer;
/* Get usernames from password file */
for(ptr = bufptr; *ptr!=':'; ptr++);
}
strncpy(username, buffer, len);
username[len] = '\0';
-
+
/* Hash the username */
- hashindex = hashUserName(username);
+ hashindex = hashUserName(username);
/*printf("%s:%d\n", username, hashindex);*/
-
+
/* Allocate space for structure to go in hashtable */
new = (struct mypasswd *)rad_malloc(sizeof(struct mypasswd));
memset(new, 0, sizeof(struct mypasswd));
-
+
/* Put username into new structure */
new->pw_name = (char *)rad_malloc(strlen(username)+1);
strncpy(new->pw_name, username, strlen(username)+1);
-
+
/* Put passwords into array, if not shadowed */
/* Get passwords from password file (shadow comes later) */
ptr++;
bufptr = ptr;
while(*ptr!=':')
ptr++;
-
+
#if !HAVE_SHADOW_H
/* Put passwords into new structure (*/
len = ptr - bufptr;
-
+
if (len > 0) {
new->pw_passwd = (char *)rad_malloc(len+1);
strncpy(new->pw_passwd, bufptr, len);
} else {
new->pw_passwd = NULL;
}
-
-#endif /* !HAVE_SHADOW_H */
-
- /*
- * Put uid into structure. Not sure why, but
+
+#endif /* !HAVE_SHADOW_H */
+
+ /*
+ * Put uid into structure. Not sure why, but
* at least we'll have it later if we need it
*/
ptr++;
len = ptr - bufptr;
strncpy(idtmp, bufptr, len);
idtmp[len] = '\0';
- new->pw_uid = (uid_t)atoi(idtmp);
-
- /*
- * Put gid into structure.
+ new->pw_uid = (uid_t)atoi(idtmp);
+
+ /*
+ * Put gid into structure.
*/
ptr++;
bufptr = ptr;
len = ptr - bufptr;
strncpy(idtmp, bufptr, len);
idtmp[len] = '\0';
- new->pw_gid = (gid_t)atoi(idtmp);
-
- /*
- * Put name into structure.
+ new->pw_gid = (gid_t)atoi(idtmp);
+
+ /*
+ * Put name into structure.
*/
ptr++;
bufptr = ptr;
while(*ptr!=':')
ptr++;
-
+
len = ptr - bufptr;
new->pw_gecos = (char *)rad_malloc(len+1);
strncpy(new->pw_gecos, bufptr, len);
new->pw_gecos[len] = '\0';
-
- /*
+
+ /*
* We'll skip home dir and shell
* as I can't think of any use for storing them
*/
-
+
/*printf("User: %s, UID: %d, GID: %d\n", new->pw_name, new->pw_uid, new->pw_gid);*/
/* Store user in the hash */
storeHashUser(cache, new, hashindex);
continue;
}
- /*
+ /*
* In order to put passwd in correct structure, we have
* to skip any struct that has a passwd already for that
* user
- */
+ */
cur = new;
- while(new && (strcmp(new->pw_name, username)<=0)
+ while(new && (strcmp(new->pw_name, username)<=0)
&& (new->pw_passwd == NULL)) {
cur = new;
new = new->next;
- }
+ }
/* Go back one, we passed it in the above loop */
new = cur;
/*
* When we get here, we should be at the last duplicate
* user structure in this hash bucket
- */
+ */
/* Put passwords into struct from shadow file */
ptr++;
/* Make new mygroup structure in mem */
g_new = (struct mygroup *)rad_malloc(sizeof(struct mygroup));
memset(g_new, 0, sizeof(struct mygroup));
-
+
/* copy grp entries to my structure */
len = strlen(grp->gr_name);
g_new->gr_name = (char *)rad_malloc(len+1);
strncpy(g_new->gr_name, grp->gr_name, len);
g_new->gr_name[len] = '\0';
-
+
len = strlen(grp->gr_passwd);
g_new->gr_passwd= (char *)rad_malloc(len+1);
strncpy(g_new->gr_passwd, grp->gr_passwd, len);
g_new->gr_passwd[len] = '\0';
- g_new->gr_gid = grp->gr_gid;
-
+ g_new->gr_gid = grp->gr_gid;
+
/* Allocate space for user list, as much as I hate doing groups
- * that way.
+ * that way.
*/
for(member = grp->gr_mem; *member!=NULL; member++);
len = member - grp->gr_mem;
cur = next;
}
}
- }
+ }
g_cur = cache->grphead;
free(g_cur->gr_passwd);
free(g_cur);
g_cur = g_next;
- }
+ }
free(cache);
}
/*
- * Looks up user in hashtable. If user can't be found, returns 0.
+ * Looks up user in hashtable. If user can't be found, returns 0.
* Otherwise returns a pointer to the structure for the user
*/
static struct mypasswd *findHashUser(struct pwcache *cache, const char *user)
}
return (hash % HASHTABLESIZE);
-}
+}
/*
- * Emulate the cistron unix_pass function, but do it using
+ * Emulate the cistron unix_pass function, but do it using
* our hashtable (iow, make it blaze).
* return 0 on success
* return -1 on failure
if(mainconfig.do_usercollide) {
while(pwd) {
- /*
+ /*
* Make sure same user still. If not, return as if
- * wrong pass given
+ * wrong pass given
*/
- if(strcmp(name, pwd->pw_name))
- return -1;
-
- /*
+ if(strcmp(name, pwd->pw_name))
+ return -1;
+
+ /*
* Could still be null passwd
*/
encrypted_pass = pwd->pw_passwd;
if (encrypted_pass == NULL) {
return 0;
}
-
- /*
+
+ /*
* Check password
*/
if(lrad_crypt_check(passwd, encrypted_pass) == 0) {
- /*
+ /*
* Add 'Class' pair here with value of full
* name from passwd
*/
if(strlen(pwd->pw_gecos))
pairadd(reply_items, pairmake("Class", pwd->pw_gecos, T_OP_EQ));
-
- return 0;
+
+ return 0;
}
pwd = pwd->next;
}
- /*
- * If we get here, pwd is null, and no users matched
+ /*
+ * If we get here, pwd is null, and no users matched
*/
return -1;
} else {
if(cache->grphead) {
cur = cache->grphead;
while((cur) && (strcmp(cur->gr_name, (char *)check->strvalue))){
- cur = cur->next;
- }
+ cur = cur->next;
+ }
/* found the group, now compare it */
if(!cur) {
/* Default to old function if we can't find it */
* cache.h Definitions for structures and functions needed in cache.c
*
* Version: cache.c 0.99 04-13-1999 jeff@apex.net
- */
+ */
#ifndef _CACHE_H
#define _CACHE_H
gid_t gr_gid; /* group id */
char **gr_mem; /* group members */
struct mygroup *next; /* next */
-};
+};
struct pwcache {
struct mypasswd *hashtable[HASHTABLESIZE];
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Copyright 2001 The FreeRADIUS server project.
- */
+ */
static const char rcsid[] = "$Id$";
#include "autoconf.h"
ptr = buffer;
RAD_EXTRACT_FIELD("Username", username);
pwbuf.pw_name = username;
-
+
/* Get (encrypted) password from password file (shadow comes later) */
if (*ptr != '\0') ptr++;
RAD_EXTRACT_FIELD("Password", userpwd);
if (*ptr != '\0') ptr++;
RAD_EXTRACT_FIELD("UID", uidtmp);
pwbuf.pw_uid = atoi(uidtmp);
-
+
/* Get gid from the password file */
if (*ptr != '\0') ptr++;
RAD_EXTRACT_FIELD("GID", gidtmp);
pwbuf.pw_gid = atoi(gidtmp);
-
+
/* Get the GECOS (name) field from the password file */
if (*ptr != '\0') ptr++;
RAD_EXTRACT_FIELD("GECOS", gecostmp);
ptr = buffer;
RAD_EXTRACT_FIELD("Username", username);
GET_SP_NAME(&spbuf) = username;
-
+
/* Get (encrypted) passwords from the shadow file */
if (*ptr != '\0') ptr++;
RAD_EXTRACT_FIELD("Password", userpwd);
* of the routines that we would like to use...
*
* Version: cache.c 0.99 04-13-1999 jeff@apex.net
- */
+ */
#ifndef _COMPAT_H
#define _COMPAT_H
offsetof(struct unix_instance,usegroup), NULL, "no" },
{ "cache_reload", PW_TYPE_INTEGER,
offsetof(struct unix_instance,cache_reload), NULL, "600" },
-
+
{ NULL, -1, 0, NULL, NULL } /* end the list */
};
return RLM_MODULE_FAIL;
}
fclose(fp);
- } else
+ } else
return RLM_MODULE_FAIL;
return RLM_MODULE_OK;
/*
- * crcalc.c
+ * crcalc.c
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* An attacker can learn the token's secret by observing two
* challenge/response pairs. See ANSI document X9 TG-24-1999
* <URL:http://www.x9.org/TG24_1999.pdf>.
- *
+ *
* Please read the accompanying docs.
*/
* is single-threaded.
*/
module_t rlm_x99_token = {
- "x99_token",
+ "x99_token",
RLM_TYPE_THREAD_SAFE, /* type */
x99_token_init, /* initialization */
x99_token_instantiate, /* instantiation */
/*
- * x99_util.c
+ * x99_util.c
* $Id$
*
* This program is free software; you can redistribute it and/or modify