static int krb5_instantiate(CONF_SECTION *conf, void *instance) { rlm_krb5_t *inst = instance; krb5_error_code ret; #ifndef HEIMDAL_KRB5 krb5_keytab keytab; char keytab_name[200]; char *princ_name; #endif #ifdef HEIMDAL_KRB5 DEBUG("Using Heimdal Kerberos library"); #else DEBUG("Using MIT Kerberos library"); #endif #ifndef KRB5_IS_THREAD_SAFE if (!krb5_is_thread_safe()) { WDEBUG("libkrb5 is not threadsafe, recompile it, and the server with thread support enabled"); WDEBUG("rlm_krb5 will run in single threaded mode, performance may be degraded"); } else { WDEBUG("Build time libkrb5 was not threadsafe, but run time library claims to be"); WDEBUG("Reconfigure and recompile rlm_krb5 to enable thread support"); } #endif inst->xlat_name = cf_section_name2(conf); if (!inst->xlat_name) { inst->xlat_name = cf_section_name1(conf); } ret = krb5_init_context(&inst->context); if (ret) { ERROR("rlm_krb5 (%s): context initialisation failed: %s", inst->xlat_name, rlm_krb5_error(NULL, ret)); return -1; } /* * Split service principal into service and host components * they're needed to build the server principal in MIT, * and to set the validation service in Heimdal. */ if (inst->service_princ) { size_t len; /* Service principal appears to contain a host component */ inst->hostname = strchr(inst->service_princ, '/'); if (inst->hostname) { len = (inst->hostname - inst->service_princ); inst->hostname++; } else { len = strlen(inst->service_princ); } if (len) { inst->service = talloc_array(inst, char, (len + 1)); strlcpy(inst->service, inst->service_princ, len + 1); } }
bool wice_msg_isComplete(WiceMessage *msg){ bool isCompl = ( (msg->buffer[0] == '{' && msg->buffer[msg->idx-1]=='}') || wice_msg_isFunction(msg) ); if (isCompl) { WDEBUG("message '"); WDEBUG(msg->buffer); WDEBUGLN("'"); } return isCompl; }
static int _sql_socket_destructor(rlm_sql_firebird_conn_t *conn) { int i; DEBUG2("rlm_sql_firebird: socket destructor called, closing socket"); fb_commit(conn); if (conn->dbh) { fb_free_statement(conn); isc_detach_database(conn->status, &(conn->dbh)); if (fb_error(conn)) { WDEBUG("rlm_sql_firebird: Got error " "when closing socket: %s", conn->error); } } #ifdef _PTHREAD_H pthread_mutex_destroy (&conn->mut); #endif for (i=0; i < conn->row_fcount; i++) { free(conn->row[i]); } free(conn->row); free(conn->row_sizes); fb_free_sqlda(conn->sqlda_out); free(conn->sqlda_out); free(conn->tpb); free(conn->dpb); return 0; }
/* * Compare two handlers. */ static int eap_handler_cmp(void const *a, void const *b) { int rcode; const eap_handler_t *one = a; const eap_handler_t *two = b; if (one->eap_id < two->eap_id) return -1; if (one->eap_id > two->eap_id) return +1; rcode = memcmp(one->state, two->state, sizeof(one->state)); if (rcode != 0) return rcode; /* * As of 2.1.8, we don't key off of source IP. This * a NAS to send packets load-balanced (or fail-over) * across multiple intermediate proxies, and still have * EAP work. */ if (fr_ipaddr_cmp(&one->src_ipaddr, &two->src_ipaddr) != 0) { WDEBUG("EAP packets are arriving from two different upstream " "servers. Has there been a proxy fail-over?"); } return 0; }
void doSendSerial() { char serialNumber[SERIAL_LEN] = {0}; getSerial(serialNumber, SERIAL_LEN); jsvUnLock(messageVar); messageVar = jsvVarPrintf("%s", serialNumber + SERIAL_OFFSET); WDEBUG("Serial: "); WDEBUGSTRVAR(messageVar); WDEBUGLN(""); JsVar *serial = jspGetNamedField(execInfo.root, SERIAL4_WIFI, false); jswrap_serial_print(serial, messageVar); jsvUnLock(serial); blink(PIN_RED, 20);blink(PIN_RED, 20);blink(PIN_RED, 20); }
/* * Because dlopen produces really shitty and inaccurate error messages */ static void check_lib_access(char const *name) { if (access(name, R_OK) < 0) switch (errno) { case EACCES: WDEBUG("Library \"%s\" exists, but we don't have permission to read", name); break; case ENOENT: DEBUG4("Library not found at path \"%s\"", name); break; default: DEBUG4("Possible issue accessing Library \"%s\": %s", name, strerror(errno)); break; } }
static int attr_filter_getfile(TALLOC_CTX *ctx, char const *filename, PAIR_LIST **pair_list) { vp_cursor_t cursor; int rcode; PAIR_LIST *attrs = NULL; PAIR_LIST *entry; VALUE_PAIR *vp; rcode = pairlist_read(ctx, filename, &attrs, 1); if (rcode < 0) { return -1; } /* * Walk through the 'attrs' file list. */ entry = attrs; while (entry) { entry->check = entry->reply; entry->reply = NULL; for (vp = paircursor(&cursor, &entry->check); vp; vp = pairnext(&cursor)) { /* * If it's NOT a vendor attribute, * and it's NOT a wire protocol * and we ignore Fall-Through, * then bitch about it, giving a good warning message. */ if ((vp->da->vendor == 0) && (vp->da->attr > 0xff) && (vp->da->attr > 1000)) { WDEBUG("[%s]:%d Check item \"%s\"\n\tfound in filter list for realm \"%s\".\n", filename, entry->lineno, vp->da->name, entry->name); } } entry = entry->next; } *pair_list = attrs; return 0; }
void doMeasurement() { enableDASH(); JsVar *i2c1 = jspGetNamedField(execInfo.root, "I2C1", false); IOEventFlags device = jsiGetDeviceFromClass(i2c1); if (!DEVICE_IS_I2C(device)) { blink(PIN_RED, 100); return; } jsvUnLock(i2c1); unsigned char dataPtr[2]; dataPtr[0] = CMD_MEASURE_TEMPERATURE_HOLD; jshI2CWrite(device, (unsigned char)(CMD_TEMP_ADDR), 1, (unsigned char*)dataPtr, true); int i = 0; for (i=0; i<2; i++) { dataPtr[i] = 0; } jshI2CRead(device, (unsigned char)CMD_TEMP_ADDR, 2, (unsigned char*)dataPtr, true); int temp = ((dataPtr[0] * 256) + dataPtr[1]); /// http://www.silabs.com/Support%20Documents/TechnicalDocs/Si7050-1-3-4-5-A20.pdf#page=14 JsVarFloat realTemp = ((175.72f * temp) / 65536.0f) - 46.85f; char temperatureBuffer[6] = {0}; ftoa_bounded(realTemp, temperatureBuffer, 5); temperatureBuffer[5] = '\0'; char serialNumber[SERIAL_LEN] = {0}; getSerial(serialNumber, SERIAL_LEN); /// Generate the JSON that we send to gateway skyand then to API{\"nodeSerial\":\"%s\",\"channel\":\"temp\",\"value\":\"%s\",\"metric\":\"c\"}');", serialNumber + SERIAL_OFFSE jsvUnLock(messageVar); if (doTimeout) { //regular message messageVar = jsvVarPrintf("{\"ns\":\"%s\",\"ch\":\"t\",\"v\":\"%s\",\"m\":\"c\"}", serialNumber + SERIAL_OFFSET, temperatureBuffer); } else { //this only happens if we forced the read messageVar = jsvVarPrintf("{\"ns\":\"%s\",\"ch\":\"t\",\"v\":\"%s\",\"m\":\"c\",\"f\":\"y\"}", serialNumber + SERIAL_OFFSET, temperatureBuffer); } WDEBUG("sending on DASH: "); WDEBUGSTRVAR(messageVar); WDEBUGLN(""); JsVar *serial = jspGetNamedField(execInfo.root, SERIAL1_DASH7, false); jswrap_serial_print(serial, messageVar); jsvUnLock(serial); transmittingData = true; // see jswrap_wice_idle }
// Demo for SNMP and SNMP Trap void UserSnmpDemo() { WDEBUG("\r\n\r\nStart UserSnmpDemo"); SnmpXInit(); { dataEntryType enterprise_oid = {8, {0x2b, 6, 1, 4, 1, 0, 0x10, 0}, SNMPDTYPE_OBJ_ID, 8, {"\x2b\x06\x01\x04\x01\x00\x10\x00"}, NULL, NULL}; dataEntryType trap_oid1 = {8, {0x2b, 6, 1, 4, 1, 0, 11, 0}, SNMPDTYPE_OCTET_STRING, 30, {""}, NULL, NULL}; dataEntryType trap_oid2 = {8, {0x2b, 6, 1, 4, 1, 0, 12, 0}, SNMPDTYPE_INTEGER, 4, {""}, NULL, NULL}; strcpy((int8*)trap_oid1.u.octetstring, "Alert!!!"); trap_oid2.u.intval = 123456; //SnmpXTrapSend("222.98.173.250", "127.0.0.0", "public", enterprise_oid, 1, 0, 0); //SnmpXTrapSend("222.98.173.250", "127.0.0.0", "public", enterprise_oid, 6, 0, 2, &trap_oid1, &trap_oid2); //SnmpXTrapSend("192.168.11.250", "192.168.11.251", "public", enterprise_oid, 1, 0, 0); //SnmpXTrapSend("192.168.11.250", "127.0.0.0", "public", enterprise_oid, 6, 0, 2, &trap_oid1, &trap_oid2); SnmpXTrapSend("222.98.173.214", "222.98.173.213", "public", enterprise_oid, 1, 0, 0); SnmpXTrapSend("222.98.173.214", "127.0.0.0", "public", enterprise_oid, 6, 0, 2, &trap_oid1, &trap_oid2); } SnmpXDaemon(); }
static int getusersfile(TALLOC_CTX *ctx, char const *filename, fr_hash_table_t **pht, char *compat_mode_str) { int rcode; PAIR_LIST *users = NULL; PAIR_LIST *entry, *next; fr_hash_table_t *ht, *tailht; int order = 0; if (!filename) { *pht = NULL; return 0; } rcode = pairlist_read(ctx, filename, &users, 1); if (rcode < 0) { return -1; } /* * Walk through the 'users' file list, if we're debugging, * or if we're in compat_mode. */ if ((debug_flag) || (strcmp(compat_mode_str, "cistron") == 0)) { VALUE_PAIR *vp; int compat_mode = false; if (strcmp(compat_mode_str, "cistron") == 0) { compat_mode = true; } entry = users; while (entry) { vp_cursor_t cursor; if (compat_mode) { DEBUG("[%s]:%d Cistron compatibility checks for entry %s ...", filename, entry->lineno, entry->name); } /* * Look for improper use of '=' in the * check items. They should be using * '==' for on-the-wire RADIUS attributes, * and probably ':=' for server * configuration items. */ for (vp = paircursor(&cursor, &entry->check); vp; vp = pairnext(&cursor)) { /* * Ignore attributes which are set * properly. */ if (vp->op != T_OP_EQ) { continue; } /* * If it's a vendor attribute, * or it's a wire protocol, * ensure it has '=='. */ if ((vp->da->vendor != 0) || (vp->da->attr < 0x100)) { if (!compat_mode) { WDEBUG("[%s]:%d Changing '%s =' to '%s =='\n\tfor comparing RADIUS attribute in check item list for user %s", filename, entry->lineno, vp->da->name, vp->da->name, entry->name); } else { DEBUG("\tChanging '%s =' to '%s =='", vp->da->name, vp->da->name); } vp->op = T_OP_CMP_EQ; continue; } /* * Cistron Compatibility mode. * * Re-write selected attributes * to be '+=', instead of '='. * * All others get set to '==' */ if (compat_mode) { /* * Non-wire attributes become += * * On the write attributes * become == */ if ((vp->da->attr >= 0x100) && (vp->da->attr <= 0xffff) && (vp->da->attr != PW_HINT) && (vp->da->attr != PW_HUNTGROUP_NAME)) { DEBUG("\tChanging '%s =' to '%s +='", vp->da->name, vp->da->name); vp->op = T_OP_ADD; } else { DEBUG("\tChanging '%s =' to '%s =='", vp->da->name, vp->da->name); vp->op = T_OP_CMP_EQ; } } } /* end of loop over check items */ /* * Look for server configuration items * in the reply list. * * It's a common enough mistake, that it's * worth doing. */ for (vp = paircursor(&cursor, &entry->reply); vp; vp = pairnext(&cursor)) { /* * If it's NOT a vendor attribute, * and it's NOT a wire protocol * and we ignore Fall-Through, * then bitch about it, giving a * good warning message. */ if ((vp->da->vendor == 0) && (vp->da->attr > 0xff) && (vp->da->attr > 1000)) { WDEBUG("[%s]:%d 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", filename, entry->lineno, vp->da->name, entry->name); } } entry = entry->next; } } ht = fr_hash_table_create(pairlist_hash, pairlist_cmp, my_pairlist_free); if (!ht) { pairlist_free(&users); return -1; } tailht = fr_hash_table_create(pairlist_hash, pairlist_cmp, NULL); if (!tailht) { fr_hash_table_free(ht); pairlist_free(&users); return -1; } /* * Now that we've read it in, put the entries into a hash * for faster access. */ for (entry = users; entry != NULL; entry = next) { PAIR_LIST *tail; next = entry->next; entry->next = NULL; entry->order = order++; /* * Insert it into the hash table, and remember * the tail of the linked list. */ tail = fr_hash_table_finddata(tailht, entry); if (!tail) { /* * Insert it into the head & tail. */ if (!fr_hash_table_insert(ht, entry) || !fr_hash_table_insert(tailht, entry)) { pairlist_free(&next); fr_hash_table_free(ht); fr_hash_table_free(tailht); return -1; } } else { tail->next = entry; if (!fr_hash_table_replace(tailht, entry)) { pairlist_free(&next); fr_hash_table_free(ht); fr_hash_table_free(tailht); return -1; } } } fr_hash_table_free(tailht); *pht = ht; return 0; }
static int dhcprelay_process_client_request(UNUSED REQUEST *request) { WDEBUG("DHCP Relaying requires the server to be configured with UDPFROMTO"); return -1; }
int dual_tls_recv(rad_listen_t *listener) { RADIUS_PACKET *packet; REQUEST *request; RAD_REQUEST_FUNP fun = NULL; listen_socket_t *sock = listener->data; RADCLIENT *client = sock->client; if (!tls_socket_recv(listener)) { return 0; } rad_assert(sock->request != NULL); rad_assert(sock->request->packet != NULL); rad_assert(sock->packet != NULL); rad_assert(sock->ssn != NULL); request = sock->request; packet = sock->packet; /* * Some sanity checks, based on the packet code. */ switch(packet->code) { case PW_CODE_AUTHENTICATION_REQUEST: if (listener->type != RAD_LISTEN_AUTH) goto bad_packet; FR_STATS_INC(auth, total_requests); fun = rad_authenticate; break; case PW_CODE_ACCOUNTING_REQUEST: if (listener->type != RAD_LISTEN_ACCT) goto bad_packet; FR_STATS_INC(acct, total_requests); fun = rad_accounting; break; case PW_CODE_STATUS_SERVER: if (!mainconfig.status_server) { FR_STATS_INC(auth, total_unknown_types); WDEBUG("Ignoring Status-Server request due to security configuration"); rad_free(&sock->packet); request->packet = NULL; return 0; } fun = rad_status_server; break; default: bad_packet: FR_STATS_INC(auth, total_unknown_types); DEBUG("Invalid packet code %d sent from client %s port %d : IGNORED", packet->code, client->shortname, packet->src_port); rad_free(&sock->packet); request->packet = NULL; return 0; } /* switch over packet types */ if (!request_receive(listener, packet, client, fun)) { FR_STATS_INC(auth, total_packets_dropped); rad_free(&sock->packet); request->packet = NULL; return 0; } sock->packet = NULL; /* we have no need for more partial reads */ request->packet = NULL; return 1; }
/** Convert CONFIG_PAIR (which may contain refs) to value_pair_map_t. * * Treats the left operand as an attribute reference * @verbatim<request>.<list>.<attribute>@endverbatim * * Treatment of left operand depends on quotation, barewords are treated as * attribute references, double quoted values are treated as expandable strings, * single quoted values are treated as literal strings. * * Return must be freed with talloc_free * * @param[in] ctx for talloc * @param[in] cp to convert to map. * @param[in] dst_request_def The default request to insert unqualified * attributes into. * @param[in] dst_list_def The default list to insert unqualified attributes * into. * @param[in] src_request_def The default request to resolve attribute * references in. * @param[in] src_list_def The default list to resolve unqualified attributes * in. * @return value_pair_map_t if successful or NULL on error. */ value_pair_map_t *radius_cp2map(TALLOC_CTX *ctx, CONF_PAIR *cp, request_refs_t dst_request_def, pair_lists_t dst_list_def, request_refs_t src_request_def, pair_lists_t src_list_def) { value_pair_map_t *map; char const *attr; char const *value; FR_TOKEN type; CONF_ITEM *ci = cf_pairtoitem(cp); if (!cp) return NULL; map = talloc_zero(ctx, value_pair_map_t); attr = cf_pair_attr(cp); value = cf_pair_value(cp); if (!value) { cf_log_err(ci, "Missing attribute value"); goto error; } map->dst = radius_attr2tmpl(map, attr, dst_request_def, dst_list_def); if (!map->dst) { cf_log_err(ci, "Syntax error in attribute definition"); goto error; } /* * Bare words always mean attribute references. */ type = cf_pair_value_type(cp); if (type == T_BARE_WORD) { if (*value == '&') { map->src = radius_attr2tmpl(map, value + 1, src_request_def, src_list_def); } else { if (!isdigit((int) *value) && ((strchr(value, ':') != NULL) || (dict_attrbyname(value) != NULL))) { map->src = radius_attr2tmpl(map, value, src_request_def, src_list_def); } if (map->src) { WDEBUG("%s[%d]: Please add '&' for attribute reference '%s = &%s'", cf_pair_filename(cp), cf_pair_lineno(cp), attr, value); } else { map->src = radius_str2tmpl(map, value, type); } } } else { map->src = radius_str2tmpl(map, value, type); } if (!map->src) { goto error; } map->op = cf_pair_operator(cp); map->ci = ci; /* * Lots of sanity checks for insane people... */ /* * We don't support implicit type conversion, * except for "octets" */ if (map->dst->da && map->src->da && (map->src->da->type != map->dst->da->type) && (map->src->da->type != PW_TYPE_OCTETS) && (map->dst->da->type != PW_TYPE_OCTETS)) { cf_log_err(ci, "Attribute type mismatch"); goto error; } /* * What exactly where you expecting to happen here? */ if ((map->dst->type == VPT_TYPE_ATTR) && (map->src->type == VPT_TYPE_LIST)) { cf_log_err(ci, "Can't copy list into an attribute"); goto error; } /* * Can't copy an xlat expansion or literal into a list, * we don't know what type of attribute we'd need * to create */ if ((map->dst->type == VPT_TYPE_LIST) && ((map->src->type == VPT_TYPE_XLAT) || (map->src->type == VPT_TYPE_LITERAL))) { cf_log_err(ci, "Can't copy value into list (we don't know which attribute to create)"); goto error; } /* * Depending on the attribute type, some operators are * disallowed. */ if (map->dst->type == VPT_TYPE_ATTR) { if ((map->op != T_OP_EQ) && (map->op != T_OP_CMP_EQ) && (map->op != T_OP_ADD) && (map->op != T_OP_SUB) && (map->op != T_OP_LE) && (map->op != T_OP_GE) && (map->op != T_OP_CMP_FALSE) && (map->op != T_OP_SET)) { cf_log_err(ci, "Invalid operator for attribute"); goto error; } } switch (map->src->type) { /* * Only += and -= operators are supported for list copy. */ case VPT_TYPE_LIST: switch (map->op) { case T_OP_SUB: case T_OP_ADD: break; default: cf_log_err(ci, "Operator \"%s\" not allowed " "for list copy", fr_int2str(fr_tokens, map->op, "<INVALID>")); goto error; } break; default: break; } return map; error: talloc_free(map); return NULL; }
/* * Per-instance initialization */ static int mod_instantiate(CONF_SECTION *conf, void *instance) { rlm_otp_t *inst = instance; /* Onetime initialization. */ if (!ninstance) { /* Generate a random key, used to protect the State attribute. */ otp_get_random(inst->hmac_key, sizeof(inst->hmac_key)); /* Initialize the passcode encoding/checking functions. */ otp_pwe_init(); /* * Don't do this again. * Only the main thread instantiates and detaches instances, * so this does not need mutex protection. */ ninstance++; } /* Verify ranges for those vars that are limited. */ if ((inst->challenge_len < 5) || (inst->challenge_len > OTP_MAX_CHALLENGE_LEN)) { inst->challenge_len = 6; WDEBUG("invalid challenge_length %d, " "range 5-%d, using default of 6", inst->challenge_len, OTP_MAX_CHALLENGE_LEN); } if (!inst->allow_sync && !inst->allow_async) { cf_log_err_cs(conf, "at least one of {allow_async, " "allow_sync} must be set"); return -1; } if ((inst->mschapv2_mppe_policy > 2) || (inst->mschapv2_mppe_policy < 0)) { inst->mschapv2_mppe_policy = 2; WDEBUG("Invalid value for mschapv2_mppe, " "using default of 2"); } if ((inst->mschapv2_mppe_types > 2) || (inst->mschapv2_mppe_types < 0)) { inst->mschapv2_mppe_types = 2; WDEBUG("Invalid value for " "mschapv2_mppe_bits, using default of 2"); } if ((inst->mschap_mppe_policy > 2) || (inst->mschap_mppe_policy < 0)) { inst->mschap_mppe_policy = 2; WDEBUG("Invalid value for mschap_mppe, " "using default of 2"); } if (inst->mschap_mppe_types != 2) { inst->mschap_mppe_types = 2; WDEBUG("Invalid value for " "mschap_mppe_bits, using default of 2"); } /* set the instance name (for use with authorize()) */ inst->name = cf_section_name2(conf); if (!inst->name) inst->name = cf_section_name1(conf); return 0; }
static void check_handler(void *data) { int do_warning = false; uint8_t state[8]; check_handler_t *check = data; if (!check) return; if (!check->inst || !check->handler) { free(check); return; } if (!check->inst->handler_tree) goto done; PTHREAD_MUTEX_LOCK(&(check->inst->handler_mutex)); if (!rbtree_finddata(check->inst->handler_tree, check->handler)) { goto done; } /* * The session has continued *after* this packet. * Don't do a warning. */ if (check->handler->trips > check->trips) { goto done; } /* * No TLS means no warnings. */ if (!check->handler->tls) goto done; /* * If we're being deleted early, it's likely because we * received a transmit from the client that re-uses the * same RADIUS Id, which forces the current packet to be * deleted. In that case, ignore the error. */ if (time(NULL) < (check->handler->timestamp + 3)) goto done; if (!check->handler->finished) { do_warning = true; memcpy(state, check->handler->state, sizeof(state)); } done: PTHREAD_MUTEX_UNLOCK(&(check->inst->handler_mutex)); free(check); if (do_warning) { WDEBUG("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); WDEBUG("!! EAP session with state 0x%02x%02x%02x%02x%02x%02x%02x%02x did not finish! !!", state[0], state[1], state[2], state[3], state[4], state[5], state[6], state[7]); WDEBUG("!! Please read http://wiki.freeradius.org/guide/Certificate_Compatibility !!"); WDEBUG("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); } }
/** Compare two pair lists except for the password information. * * For every element in "check" at least one matching copy must be present * in "reply". * * @param[in] request Current request. * @param[in] req_list request valuepairs. * @param[in] check Check/control valuepairs. * @param[in,out] rep_list Reply value pairs. * * @return 0 on match. */ int paircompare(REQUEST *request, VALUE_PAIR *req_list, VALUE_PAIR *check, VALUE_PAIR **rep_list) { vp_cursor_t cursor; VALUE_PAIR *check_item; VALUE_PAIR *auth_item; DICT_ATTR const *from; int result = 0; int compare; bool first_only; for (check_item = paircursor(&cursor, &check); check_item; check_item = pairnext(&cursor)) { /* * If the user is setting a configuration value, * then don't bother comparing it to any attributes * sent to us by the user. It ALWAYS matches. */ if ((check_item->op == T_OP_SET) || (check_item->op == T_OP_ADD)) { continue; } if (!check_item->da->vendor) switch (check_item->da->attr) { /* * Attributes we skip during comparison. * These are "server" check items. */ case PW_CRYPT_PASSWORD: case PW_AUTH_TYPE: case PW_AUTZ_TYPE: case PW_ACCT_TYPE: case PW_SESSION_TYPE: case PW_STRIP_USER_NAME: continue; break; /* * IF the password attribute exists, THEN * we can do comparisons against it. If not, * then the request did NOT contain a * User-Password attribute, so we CANNOT do * comparisons against it. * * This hack makes CHAP-Password work.. */ case PW_USER_PASSWORD: if (check_item->op == T_OP_CMP_EQ) { WDEBUG("Found User-Password == \"...\"."); WDEBUG("Are you sure you don't mean Cleartext-Password?"); WDEBUG("See \"man rlm_pap\" for more information"); } if (pairfind(req_list, PW_USER_PASSWORD, 0, TAG_ANY) == NULL) { continue; } break; } /* * See if this item is present in the request. */ first_only = otherattr(check_item->da, &from); auth_item = req_list; try_again: if (!first_only) { while (auth_item != NULL) { if ((auth_item->da == from) || (!from)) { break; } auth_item = auth_item->next; } } /* * Not found, it's not a match. */ if (auth_item == NULL) { /* * Didn't find it. If we were *trying* * to not find it, then we succeeded. */ if (check_item->op == T_OP_CMP_FALSE) { continue; } else { return -1; } } /* * Else we found it, but we were trying to not * find it, so we failed. */ if (check_item->op == T_OP_CMP_FALSE) { return -1; } /* * We've got to xlat the string before doing * the comparison. */ radius_xlat_do(request, check_item); /* * OK it is present now compare them. */ compare = radius_callback_compare(request, auth_item, check_item, check, rep_list); switch (check_item->op) { case T_OP_EQ: default: INFO("Invalid operator for item %s: " "reverting to '=='", check_item->da->name); /* FALL-THROUGH */ case T_OP_CMP_TRUE: case T_OP_CMP_FALSE: case T_OP_CMP_EQ: if (compare != 0) result = -1; break; case T_OP_NE: if (compare == 0) result = -1; break; case T_OP_LT: if (compare >= 0) result = -1; break; case T_OP_GT: if (compare <= 0) result = -1; break; case T_OP_LE: if (compare > 0) result = -1; break; case T_OP_GE: if (compare < 0) result = -1; break; #ifdef HAVE_REGEX_H case T_OP_REG_EQ: case T_OP_REG_NE: if (compare != 0) result = -1; break; #endif } /* switch over the operator of the check item */ /* * This attribute didn't match, but maybe there's * another of the same attribute, which DOES match. */ if ((result != 0) && (!first_only)) { auth_item = auth_item->next; result = 0; goto try_again; } } /* for every entry in the check item list */ return result; }
/* * Copied from rlm_files, and NOT under the same copyright * as the rest of the module! * * Also, it is UNNECESSARY to read the "users" file here! * Doing this shows a misunderstanding of how the server works. */ int getusersfile(TALLOC_CTX *ctx, char const *filename, PAIR_LIST **pair_list, char const *compat_mode_str) { int rcode; PAIR_LIST *users = NULL; rcode = pairlist_read(ctx, filename, &users, 1); if (rcode < 0) { return -1; } /* * Walk through the 'users' file list, if we're debugging, * or if we're in compat_mode. */ if ((debug_flag) || (strcmp(compat_mode_str, "cistron") == 0)) { PAIR_LIST *entry; VALUE_PAIR *vp; int compat_mode = false; if (strcmp(compat_mode_str, "cistron") == 0) { compat_mode = true; } entry = users; while (entry) { if (compat_mode) { DEBUG("[%s]:%d Cistron compatibility checks for entry %s ...", filename, entry->lineno, entry->name); } /* * Look for improper use of '=' in the * check items. They should be using * '==' for on-the-wire RADIUS attributes, * and probably ':=' for server * configuration items. */ for (vp = entry->check; vp != NULL; vp = vp->next) { /* * Ignore attributes which are set * properly. */ if (vp->op != T_OP_EQ) { continue; } /* * If it's a vendor attribute, * or it's a wire protocol, * ensure it has '=='. */ if ((vp->da->vendor!= 0) || (vp->da->attr < 0x100)) { if (!compat_mode) { WDEBUG("[%s]:%d Changing '%s =' to '%s =='\n\tfor comparing RADIUS attribute in check item list for user %s", filename, entry->lineno, vp->da->name, vp->da->name, entry->name); } else { DEBUG("\tChanging '%s =' to '%s =='", vp->da->name, vp->da->name); } vp->op = T_OP_CMP_EQ; continue; } /* * Cistron Compatibility mode. * * Re-write selected attributes * to be '+=', instead of '='. * * All others get set to '==' */ if (compat_mode) { /* * Non-wire attributes become += * * On the write attributes * become == */ if ((vp->da->attr >= 0x100) && (vp->da->attr <= 0xffff) && (vp->da->attr != PW_HINT) && (vp->da->attr != PW_HUNTGROUP_NAME)) { DEBUG("\tChanging '%s =' to '%s +='", vp->da->name, vp->da->name); vp->op = T_OP_ADD; } else { DEBUG("\tChanging '%s =' to '%s =='", vp->da->name, vp->da->name); vp->op = T_OP_CMP_EQ; } } } /* end of loop over check items */ /* * Look for server configuration items * in the reply list. * * It's a common enough mistake, that it's * worth doing. */ for (vp = entry->reply; vp != NULL; vp = vp->next) { /* * If it's NOT a vendor attribute, * and it's NOT a wire protocol * and we ignore Fall-Through, * then bitch about it, giving a * good warning message. */ if ((vp->da->vendor == 0) && (vp->da->attr > 0xff) && (vp->da->attr > 1000)) { WDEBUG("[%s]:%d 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", filename, entry->lineno, vp->da->name, entry->name); } } entry = entry->next; } } *pair_list = users; return 0; }
int main(void) { char *memend; int i; WDEBUG_INIT(); WDEBUG('X'); /* Pick up arguments */ kargs = (void *)__args; initial_howto = kargs->howto; initial_bootdev = kargs->bootdev; initial_bootinfo = kargs->bootinfo ? (struct bootinfo *)PTOV(kargs->bootinfo) : NULL; #ifdef COMCONSOLE_DEBUG printf("args at %p initial_howto = %08x bootdev = %08x bootinfo = %p\n", kargs, initial_howto, initial_bootdev, initial_bootinfo); #endif /* Initialize the v86 register set to a known-good state. */ bzero(&v86, sizeof(v86)); v86.efl = PSL_RESERVED_DEFAULT | PSL_I; /* * Initialize the heap as early as possible. Once this is done, * malloc() is usable. * * Don't include our stack in the heap. If the stack is in low * user memory use {end,bios_basemem}. If the stack is in high * user memory but not extended memory then don't let the heap * overlap the stack. If the stack is in extended memory limit * the heap to bios_basemem. * * Be sure to use the virtual bios_basemem address rather then * the physical bios_basemem address or we may overwrite BIOS * data. */ bios_getmem(); memend = (char *)&memend - 0x8000; /* space for stack (16K) */ memend = (char *)((uintptr_t)memend & ~(uintptr_t)(0x1000 - 1)); /* * For day to day usage simple memend setup is more than engouh, * but bigger heap is a must for loading bzipp'ed kernel/modules * "bzf_read: BZ2_bzDecompress returned -3" */ #if defined(LOADER_BZIP2_SUPPORT) if (high_heap_size > 0) { heap_top = PTOV(high_heap_base + high_heap_size); heap_bottom = PTOV(high_heap_base); if (high_heap_base < memtop_copyin) memtop_copyin = high_heap_base; } else #endif if (memend < (char *)_end) { heap_top = PTOV(bios_basemem); heap_bottom = (void *)_end; } else { if (memend > (char *)PTOV(bios_basemem)) memend = (char *)PTOV(bios_basemem); heap_top = memend; heap_bottom = (void *)_end; } setheap(heap_bottom, heap_top); /* * XXX Chicken-and-egg problem; we want to have console output early, * but some console attributes may depend on reading from eg. the boot * device, which we can't do yet. * * We can use printf() etc. once this is done. The previous boot stage * might have requested a video or serial preference, in which case we * set it. */ bi_setboothowto(initial_howto); if (initial_howto & RB_MUTE) { setenv("console", "nullconsole", 1); } else if ((initial_howto & (RB_VIDEO|RB_SERIAL)) == (RB_VIDEO|RB_SERIAL)) { setenv("console", "vidconsole comconsole", 1); } else if (initial_howto & RB_VIDEO) { setenv("console", "vidconsole", 1); } else if (initial_howto & RB_SERIAL) { setenv("console", "comconsole", 1); } else { /* XXX leave to cons_probe() */ } cons_probe(); /* * Initialise the block cache */ bcache_init(32, 512); /* 16k cache XXX tune this */ /* * Special handling for PXE and CD booting. */ if (kargs->bootinfo == 0) { /* * We only want the PXE disk to try to init itself in the below * walk through devsw if we actually booted off of PXE. */ if (kargs->bootflags & KARGS_FLAGS_PXE) pxe_enable(kargs->pxeinfo ? PTOV(kargs->pxeinfo) : NULL); else if (kargs->bootflags & KARGS_FLAGS_CD) bc_add(initial_bootdev); } archsw.arch_autoload = i386_autoload; archsw.arch_getdev = i386_getdev; archsw.arch_copyin = i386_copyin; archsw.arch_copyout = i386_copyout; archsw.arch_readin = i386_readin; archsw.arch_isainb = isa_inb; archsw.arch_isaoutb = isa_outb; /* * March through the device switch probing for things. */ for (i = 0; devsw[i] != NULL; i++) { WDEBUG('M' + i); if (devsw[i]->dv_init != NULL) (devsw[i]->dv_init)(); WDEBUG('M' + i); } printf("BIOS %dkB/%dkB available memory\n", bios_basemem / 1024, bios_extmem / 1024); if (initial_bootinfo != NULL) { initial_bootinfo->bi_basemem = bios_basemem / 1024; initial_bootinfo->bi_extmem = bios_extmem / 1024; } /* detect ACPI for future reference */ biosacpi_detect(); /* detect SMBIOS for future reference */ smbios_detect(NULL); /* detect PCI BIOS for future reference */ biospci_detect(); /* enable EHCI */ setenv("ehci_load", "YES", 1); /* enable XHCI */ setenv("xhci_load", "YES", 1); printf("\n"); printf("%s, Revision %s\n", bootprog_name, bootprog_rev); printf("(%s, %s)\n", bootprog_maker, bootprog_date); extract_currdev(); /* set $currdev and $loaddev */ setenv("LINES", "24", 1); /* optional */ bios_getsmap(); interact(); /* doesn't return */ /* if we ever get here, it is an error */ return (1); }
/** Convert CONFIG_PAIR (which may contain refs) to value_pair_map_t. * * Treats the left operand as an attribute reference * @verbatim<request>.<list>.<attribute>@endverbatim * * Treatment of left operand depends on quotation, barewords are treated as * attribute references, double quoted values are treated as expandable strings, * single quoted values are treated as literal strings. * * Return must be freed with talloc_free * * @param[in] ctx for talloc * @param[in] cp to convert to map. * @param[in] dst_request_def The default request to insert unqualified * attributes into. * @param[in] dst_list_def The default list to insert unqualified attributes * into. * @param[in] src_request_def The default request to resolve attribute * references in. * @param[in] src_list_def The default list to resolve unqualified attributes * in. * @return value_pair_map_t if successful or NULL on error. */ value_pair_map_t *radius_cp2map(TALLOC_CTX *ctx, CONF_PAIR *cp, request_refs_t dst_request_def, pair_lists_t dst_list_def, request_refs_t src_request_def, pair_lists_t src_list_def) { value_pair_map_t *map; char const *attr; char const *value; FR_TOKEN type; CONF_ITEM *ci = cf_pairtoitem(cp); if (!cp) return NULL; map = talloc_zero(ctx, value_pair_map_t); map->op = cf_pair_operator(cp); map->ci = ci; attr = cf_pair_attr(cp); value = cf_pair_value(cp); if (!value) { cf_log_err(ci, "Missing attribute value"); goto error; } /* * LHS must always be an attribute reference. */ map->dst = radius_attr2tmpl(map, attr, dst_request_def, dst_list_def); if (!map->dst) { cf_log_err(ci, "Syntax error in attribute definition"); goto error; } /* * RHS might be an attribute reference. */ type = cf_pair_value_type(cp); map->src = radius_str2tmpl(map, value, type, src_request_def, src_list_def); if (!map->src) { goto error; } /* * Anal-retentive checks. */ if (debug_flag > 2) { if ((map->dst->type == VPT_TYPE_ATTR) && (*attr != '&')) { WDEBUG("%s[%d]: Please change attribute reference to '&%s %s ...'", cf_pair_filename(cp), cf_pair_lineno(cp), attr, fr_int2str(fr_tokens, map->op, "<INVALID>")); } if ((map->src->type == VPT_TYPE_ATTR) && (*value != '&')) { WDEBUG("%s[%d]: Please change attribute reference to '... %s &%s'", cf_pair_filename(cp), cf_pair_lineno(cp), fr_int2str(fr_tokens, map->op, "<INVALID>"), value); } } /* * Lots of sanity checks for insane people... */ /* * We don't support implicit type conversion, * except for "octets" */ if (map->dst->vpt_da && map->src->vpt_da && (map->src->vpt_da->type != map->dst->vpt_da->type) && (map->src->vpt_da->type != PW_TYPE_OCTETS) && (map->dst->vpt_da->type != PW_TYPE_OCTETS)) { cf_log_err(ci, "Attribute type mismatch"); goto error; } /* * What exactly where you expecting to happen here? */ if ((map->dst->type == VPT_TYPE_ATTR) && (map->src->type == VPT_TYPE_LIST)) { cf_log_err(ci, "Can't copy list into an attribute"); goto error; } /* * Depending on the attribute type, some operators are * disallowed. */ if (map->dst->type == VPT_TYPE_ATTR) { if ((map->op != T_OP_EQ) && (map->op != T_OP_CMP_EQ) && (map->op != T_OP_ADD) && (map->op != T_OP_SUB) && (map->op != T_OP_LE) && (map->op != T_OP_GE) && (map->op != T_OP_CMP_FALSE) && (map->op != T_OP_SET)) { cf_log_err(ci, "Invalid operator for attribute"); goto error; } /* * This will be an error in future versions of * the server. */ if ((map->op == T_OP_CMP_FALSE) && ((map->src->type != VPT_TYPE_LITERAL) || (strcmp(map->src->name, "ANY") != 0))) { WDEBUG("%s[%d] Attribute deletion MUST use '!* ANY'", cf_pair_filename(cp), cf_pair_lineno(cp)); } } if (map->dst->type == VPT_TYPE_LIST) { /* * Only += and :=, and !* operators are supported * for lists. */ switch (map->op) { case T_OP_CMP_FALSE: if ((map->src->type != VPT_TYPE_LITERAL) || (strcmp(map->src->name, "ANY") != 0)) { cf_log_err(ci, "List deletion MUST use '!* ANY'"); goto error; } break; case T_OP_ADD: if ((map->src->type != VPT_TYPE_LIST) && (map->src->type != VPT_TYPE_EXEC)) { cf_log_err(ci, "Invalid source for list '+='"); goto error; } break; case T_OP_SET: if (map->src->type == VPT_TYPE_EXEC) { WDEBUG("%s[%d] Please change ':=' to '=' for list assignment", cf_pair_filename(cp), cf_pair_lineno(cp)); break; } if (map->src->type != VPT_TYPE_LIST) { cf_log_err(ci, "Invalid source for ':=' operator"); goto error; } break; case T_OP_EQ: if (map->src->type != VPT_TYPE_EXEC) { cf_log_err(ci, "Invalid source for '=' operator"); goto error; } break; default: cf_log_err(ci, "Operator \"%s\" not allowed for list assignment", fr_int2str(fr_tokens, map->op, "<INVALID>")); goto error; } } return map; error: talloc_free(map); return NULL; }