/** Get the hostname of this machine * * @param hostname will hold the name of the host. * @param len the size of hostname. * @return -1 on failure, 0 on success. */ int rc_own_hostname(char *hostname, int len) { #ifdef HAVE_UNAME struct utsname uts; #endif #if defined(HAVE_UNAME) if (uname(&uts) < 0) { rc_log(LOG_ERR,"rc_own_hostname: couldn't get own hostname"); return -1; } strlcpy(hostname, uts.nodename, len); #elif defined(HAVE_GETHOSTNAME) if (gethostname(hostname, len) < 0) { rc_log(LOG_ERR,"rc_own_hostname: couldn't get own hostname"); return -1; } #elif defined(HAVE_SYSINFO) if (sysinfo(SI_HOSTNAME, hostname, len) < 0) { rc_log(LOG_ERR,"rc_own_hostname: couldn't get own hostname"); return -1; } #else return -1; #endif return 0; }
VALUE_PAIR *rc_avpair_new (int attrid, void *pval, int len, int vendorcode) { VALUE_PAIR *vp = (VALUE_PAIR *) NULL; DICT_ATTR *pda; if ((pda = rc_dict_getattr (attrid, vendorcode)) == (DICT_ATTR *) NULL) { rc_log(LOG_ERR,"rc_avpair_new: unknown attribute %d", attrid); } else { if ((vp = (VALUE_PAIR *) malloc (sizeof (VALUE_PAIR))) != (VALUE_PAIR *) NULL) { strncpy (vp->name, pda->name, sizeof (vp->name)); vp->attribute = attrid; vp->vendorcode = vendorcode; vp->next = (VALUE_PAIR *) NULL; vp->type = pda->type; if (rc_avpair_assign (vp, pval, len) == 0) { return vp; } free (vp); vp = (VALUE_PAIR *) NULL; } else { rc_log(LOG_CRIT,"rc_avpair_new: out of memory"); } } return vp; }
/** Find outbound interface address for a given destination * * Given remote address find local address which the system will use as a source address for sending * datagrams to that remote address. * * @param lia local address. * @param ria the remove address. * @return 0 in success, -1 on failure, address is filled into the first argument. */ int rc_get_srcaddr(struct sockaddr *lia, const struct sockaddr *ria) { int temp_sock; socklen_t namelen; temp_sock = socket(ria->sa_family, SOCK_DGRAM, 0); if (temp_sock == -1) { rc_log(LOG_ERR, "rc_get_srcaddr: socket: %s", strerror(errno)); return -1; } if (connect(temp_sock, ria, SA_LEN(ria)) != 0) { rc_log(LOG_ERR, "rc_get_srcaddr: connect: %s", strerror(errno)); close(temp_sock); return -1; } namelen = SA_LEN(ria); if (getsockname(temp_sock, lia, &namelen) != 0) { rc_log(LOG_ERR, "rc_get_srcaddr: getsockname: %s", strerror(errno)); close(temp_sock); return -1; } close(temp_sock); return 0; }
static int apply_config(rc_handle *rh) { memset(&rh->own_bind_addr, 0, sizeof(rh->own_bind_addr)); rh->own_bind_addr_set = 0; rc_own_bind_addr(rh, &rh->own_bind_addr); rh->own_bind_addr_set = 1; #ifdef HAVE_GNUTLS { const char *txt; int ret; txt = rc_conf_str(rh, "serv-auth-type"); if (txt != NULL) { if (strcasecmp(txt, "dtls") == 0) { ret = rc_init_tls(rh, SEC_FLAG_DTLS); } else if (strcasecmp(txt, "tls") == 0) { ret = rc_init_tls(rh, 0); } else { rc_log(LOG_CRIT, "unknown server authentication type: %s", txt); return -1; } if (ret < 0) { rc_log(LOG_CRIT, "error initializing %s", txt); return -1; } } } #endif return 0; }
char *rc_getifname(rc_handle *rh, char *tty) { #if defined(BSD4_4) || defined(linux) int fd; if ((fd = open(tty, O_RDWR|O_NDELAY)) < 0) { rc_log(LOG_ERR, "rc_getifname: can't open %s: %s", tty, strerror(errno)); return NULL; } #endif #ifdef BSD4_4 strcpy(rh->ifname,ttyname(fd)); if (strlen(rh->ifname) < 1) { rc_log(LOG_ERR, "rc_getifname: can't get attached interface of %s: %s", tty, strerror(errno)); close(fd); return NULL; } #elif linux if (ioctl(fd, SIOCGIFNAME, rh->ifname) < 0) { rc_log(LOG_ERR, "rc_getifname: can't ioctl %s: %s", tty, strerror(errno)); close(fd); return NULL; } #else return NULL; #endif #if defined(BSD4_4) || defined(linux) close(fd); return rh->ifname; #endif }
/** Make a new attribute-value pair with given parameters * * @param rh a handle to parsed configuration. * @param attrid The attribute of the pair to add (e.g., %PW_USER_NAME). * @param pval the value (e.g., the actual username). * @param len the length of pval, or -1 if to calculate (in case of strings). * @param vendorpec The vendor ID in case of a vendor specific value - 0 otherwise. * @return pointer to generated a/v pair when successful, NULL when failure. */ VALUE_PAIR *rc_avpair_new (rc_handle const *rh, int attrid, void const *pval, int len, int vendorpec) { VALUE_PAIR *vp = NULL; DICT_ATTR *pda; attrid = attrid | (vendorpec << 16); if ((pda = rc_dict_getattr (rh, attrid)) == NULL) { rc_log(LOG_ERR,"rc_avpair_new: unknown attribute %d", attrid); return NULL; } if (vendorpec != 0 && rc_dict_getvend(rh, vendorpec) == NULL) { rc_log(LOG_ERR,"rc_avpair_new: unknown Vendor-Id %d", vendorpec); return NULL; } if ((vp = malloc (sizeof (VALUE_PAIR))) != NULL) { strlcpy (vp->name, pda->name, sizeof (vp->name)); vp->attribute = attrid; vp->next = NULL; vp->type = pda->type; if (rc_avpair_assign (vp, pval, len) == 0) { /* XXX: Fix up Digest-Attributes */ switch (vp->attribute) { case PW_DIGEST_REALM: case PW_DIGEST_NONCE: case PW_DIGEST_METHOD: case PW_DIGEST_URI: case PW_DIGEST_QOP: case PW_DIGEST_ALGORITHM: case PW_DIGEST_BODY_DIGEST: case PW_DIGEST_CNONCE: case PW_DIGEST_NONCE_COUNT: case PW_DIGEST_USER_NAME: /* overlapping! */ if (vp->lvalue > AUTH_STRING_LEN - 2) vp->lvalue = AUTH_STRING_LEN - 2; memmove(&vp->strvalue[2], &vp->strvalue[0], vp->lvalue); vp->strvalue[0] = vp->attribute - PW_DIGEST_REALM + 1; vp->lvalue += 2; vp->strvalue[1] = vp->lvalue; vp->strvalue[vp->lvalue] = '\0'; vp->attribute = PW_DIGEST_ATTRIBUTES; default: break; } return vp; } free (vp); vp = NULL; } else { rc_log(LOG_CRIT,"rc_avpair_new: out of memory"); } return vp; }
/** * @brief Read data from a resource (unlocked) * * @param resouce The resource to read from * * @return The same return value as read_packet */ int r_read(Resource *resource) { int ret = RESOURCE_EOF; g_mutex_lock(resource->lock); if (!resource->eor) switch( (ret = resource->demuxer->read_packet(resource)) ) { case RESOURCE_OK: break; case RESOURCE_EOF: rc_log(RC_LOG_INFO, "r_read_unlocked: %s read_packet() end of file.", resource->info->mrl); resource->eor = TRUE; break; default: rc_log(RC_LOG_FATAL, "r_read_unlocked: %s read_packet() error.", resource->info->mrl); break; } g_mutex_unlock(resource->lock); return ret; }
unsigned char rc_get_seqnbr(void) { FILE *sf; int tries = 1; int seq_nbr, pos; char *seqfile = rc_conf_str("seqfile"); if ((sf = fopen(seqfile, "a+")) == NULL) { rc_log(LOG_ERR,"rc_get_seqnbr: couldn't open sequence file %s: %s", seqfile, strerror(errno)); /* well, so guess a sequence number */ return rc_guess_seqnbr(); } while (do_lock_exclusive(fileno(sf))!= 0) { if (errno != EWOULDBLOCK) { rc_log(LOG_ERR, "rc_get_seqnbr: flock failure: %s: %s", seqfile, strerror(errno)); fclose(sf); return rc_guess_seqnbr(); } tries++; if (tries <= 10) rc_mdelay(500); else break; } if (tries > 10) { rc_log(LOG_ERR,"rc_get_seqnbr: couldn't get lock after %d tries: %s", tries-1, seqfile); fclose(sf); return rc_guess_seqnbr(); } pos = ftell(sf); rewind(sf); if (fscanf(sf, "%d", &seq_nbr) != 1) { if (pos != ftell(sf)) { /* file was not empty */ rc_log(LOG_ERR,"rc_get_seqnbr: fscanf failure: %s", seqfile); } seq_nbr = rc_guess_seqnbr(); } rewind(sf); ftruncate(fileno(sf),0); fprintf(sf,"%d\n", (seq_nbr+1) & UCHAR_MAX); fflush(sf); /* fflush because a process may read it between the do_unlock and fclose */ if (do_unlock(fileno(sf)) != 0) rc_log(LOG_ERR, "rc_get_seqnbr: couldn't release lock on %s: %s", seqfile, strerror(errno)); fclose(sf); return (unsigned char)seq_nbr; }
static int set_option_auo(char const *filename, int line, OPTION *option, char const *p) { int *iptr; char *p_dupe = NULL; char *p_pointer = NULL; char *p_save = NULL; p_dupe = strdup(p); if (p_dupe == NULL) { rc_log(LOG_WARNING, "%s: line %d: bogus option value", filename, line); return -1; } if ((iptr = malloc(sizeof(iptr))) == NULL) { rc_log(LOG_CRIT, "read_config: out of memory"); free(p_dupe); return -1; } *iptr = 0; /*if(strstr(p_dupe,", \t") != NULL) {*/ p_pointer = strtok_r(p_dupe, ", \t", &p_save); /*}*/ if (!strncmp(p_pointer, "local", 5)) *iptr = AUTH_LOCAL_FST; else if (!strncmp(p_pointer, "radius", 6)) *iptr = AUTH_RADIUS_FST; else { rc_log(LOG_ERR,"%s: auth_order: unknown keyword: %s", filename, p); free(iptr); free(p_dupe); return -1; } p_pointer = strtok_r(NULL, ", \t", &p_save); if (p_pointer && (*p_pointer != '\0')) { if ((*iptr & AUTH_RADIUS_FST) && !strcmp(p_pointer, "local")) *iptr = (*iptr) | AUTH_LOCAL_SND; else if ((*iptr & AUTH_LOCAL_FST) && !strcmp(p_pointer, "radius")) *iptr = (*iptr) | AUTH_RADIUS_SND; else { rc_log(LOG_ERR,"%s: auth_order: unknown or unexpected keyword: %s", filename, p); free(iptr); free(p_dupe); return -1; } } option->val = (void *) iptr; free(p_dupe); return 0; }
/** * @brief Open a new resource and create a new instance * * @param srv The server object for the vhost requesting the resource * @param inner_path The path, relative to the avroot, for the * resource * * @return A new Resource object * @retval NULL Error while opening resource */ Resource *r_open(const char *inner_path, OpenMode mode) { Resource *r; const Demuxer *dmx; gchar *mrl, *path; gint ls, ls_store; /* ls: use demuxer_ls; ls_store: demuxer_ls with history streams */ path = get_media_path(inner_path, &ls, &ls_store); mrl = g_strdup_printf("%s%s", RESOURCE_ROOT, path); g_free(path); if ((dmx = r_find_demuxer(mrl)) == NULL) { rc_log(RC_LOG_DEBUG, "[MT] Could not find a valid demuxer for resource %s\n", mrl); goto error; } rc_log(RC_LOG_DEBUG, "[MT] registrered demuxer \"%s\" for resource" "\"%s\"\n", dmx->info->name, mrl); r = g_slice_new0(Resource); r->info = g_slice_new0(ResourceInfo); r->info->mrl = mrl; r->info->mtime = 0; r->info->name = g_path_get_basename(mrl); r->info->seekable = (dmx->seek != NULL); if (ls && !ls_store) r->info->seekable = FALSE; r->demuxer = dmx; r->mode = mode; if (r->demuxer->init(r)) { r_free_cb(r, NULL); return NULL; } /* Now that we have opened the actual resource we can proceed with * the extras */ r->lock = g_mutex_new(); #ifdef HAVE_METADATA cpd_find_request(srv, r, filename); #endif return r; error: g_free(mrl); return NULL; }
/** Allow a config option to be added to rc_handle from inside a program * * @param rh a handle to parsed configuration. * @param option_name the name of the option. * @param option_val the value to be added. * @param source typically should be %__FILE__ or %__func__ for logging purposes. * @param line %__LINE__ for logging purposes. * @return 0 on success, -1 on failure. */ int rc_add_config(rc_handle *rh, char const *option_name, char const *option_val, char const *source, int line) { OPTION *option; if ((option = find_option(rh, option_name, OT_ANY)) == NULL) { rc_log(LOG_ERR, "ERROR: unrecognized option: %s", option_name); return -1; } if (option->status != ST_UNDEF) { rc_log(LOG_ERR, "ERROR: duplicate option: %s", option_name); return -1; } switch (option->type) { case OT_STR: if (set_option_str(source, line, option, option_val) < 0) { return -1; } break; case OT_INT: if (set_option_int(source, line, option, option_val) < 0) { return -1; } break; case OT_SRV: if (set_option_srv(source, line, option, option_val) < 0) { return -1; } break; case OT_AUO: if (set_option_auo(source, line, option, option_val) < 0) { return -1; } break; default: rc_log(LOG_CRIT, "rc_add_config: impossible case branch!"); abort(); } if (strcmp(option->name, "bindaddr") == 0) { memset(&rh->own_bind_addr, 0, sizeof(rh->own_bind_addr)); rh->own_bind_addr_set = 0; rc_own_bind_addr(rh, &rh->own_bind_addr); rh->own_bind_addr_set = 1; } return 0; }
static int set_option_srv(char *filename, int line, OPTION *option, char *p) { SERVER *serv; char *q; struct servent *svp; int i; if (p == NULL) { rc_log(LOG_ERR, "%s: line %d: bogus option value", filename, line); return (-1); } serv = (SERVER *) option->val; for (i = 0; i < serv->max; i++) { free(serv->name[i]); } serv->max = 0; while ((p = strtok(p, ", \t")) != NULL) { if ((q = strchr(p,':')) != NULL) { *q = '\0'; q++; serv->port[serv->max] = atoi(q); } else { if (!strcmp(option->name,"authserver")) if ((svp = getservbyname ("radius", "udp")) == NULL) serv->port[serv->max] = PW_AUTH_UDP_PORT; else serv->port[serv->max] = ntohs ((unsigned int) svp->s_port); else if (!strcmp(option->name, "acctserver")) if ((svp = getservbyname ("radacct", "udp")) == NULL) serv->port[serv->max] = PW_ACCT_UDP_PORT; else serv->port[serv->max] = ntohs ((unsigned int) svp->s_port); else { rc_log(LOG_ERR, "%s: line %d: no default port for %s", filename, line, option->name); return (-1); } } serv->name[serv->max++] = strdup(p); p = NULL; } return 0; }
/** Find our source address * * Get the IP address to be used as a source address * for sending requests in host order. * * @param rh a handle to parsed configuration * @param lia the local address to listen to * **/ void rc_own_bind_addr(rc_handle *rh, struct sockaddr_storage *lia) { char *txtaddr = rc_conf_str(rh, "bindaddr"); struct addrinfo *info; if (rh->own_bind_addr_set) { memcpy(lia, &rh->own_bind_addr, SS_LEN(&rh->own_bind_addr)); return; } memset(lia, 0, sizeof(*lia)); if (txtaddr == NULL || txtaddr[0] == '*') { ((struct sockaddr_in*)lia)->sin_family = AF_INET; ((struct sockaddr_in*)lia)->sin_addr.s_addr = INADDR_ANY; } else { info = rc_getaddrinfo (txtaddr, PW_AI_PASSIVE); if (info == NULL) { rc_log(LOG_ERR, "rc_own_ipaddress: couldn't get IP address from bindaddr"); ((struct sockaddr_in*)lia)->sin_family = AF_INET; ((struct sockaddr_in*)lia)->sin_addr.s_addr = INADDR_ANY; return; } memcpy(lia, info->ai_addr, info->ai_addrlen); } return; }
gint r_ctrl(const char *inner_path, gint cmd, void *value) { const Demuxer *dmx; gchar *mrl, *path; gint ls, ls_store, ret = -1; path = get_media_path(inner_path, &ls, &ls_store); mrl = g_strdup_printf("%s%s", RESOURCE_ROOT, path); g_free(path); if (ls) { if ((dmx = r_find_demuxer(mrl)) == NULL) { rc_log(RC_LOG_DEBUG, "[MT] Could not find a valid demuxer for '%s'\n", mrl); g_free(mrl); return -1; } if (dmx->ctrl_track) ret = (*dmx->ctrl_track)(mrl, cmd, value); g_free(mrl); return ret; } g_free(mrl); return -1; }
/** Assigns the given value to an attribute-value pair * * @param vp a pointer to a #VALUE_PAIR structure. * @param pval the value (e.g., the actual username). * @param len the length of @pval, or -1 if to calculate (in case of strings). * @return 0 on success or -1 on failure. */ int rc_avpair_assign (VALUE_PAIR *vp, void const *pval, int len) { switch (vp->type) { case PW_TYPE_STRING: if (len == -1) len = (uint32_t)strlen((char const *)pval); if (len > AUTH_STRING_LEN) { rc_log(LOG_ERR, "rc_avpair_assign: bad attribute length"); return -1; } memcpy(vp->strvalue, (char const *)pval, len); vp->strvalue[len] = '\0'; vp->lvalue = len; break; case PW_TYPE_DATE: case PW_TYPE_INTEGER: case PW_TYPE_IPADDR: vp->lvalue = * (uint32_t *) pval; break; case PW_TYPE_IPV6ADDR: if (len != 16) { rc_log(LOG_ERR, "rc_avpair_assign: bad IPv6 length"); return -1; } memcpy(vp->strvalue, (char const *)pval, len); vp->lvalue = len; break; case PW_TYPE_IPV6PREFIX: if (len < 2 || len > 18) { rc_log(LOG_ERR, "rc_avpair_assign: bad IPv6 prefix length"); return -1; } memcpy(vp->strvalue, (char const *)pval, len); vp->lvalue = len; break; default: rc_log(LOG_ERR, "rc_avpair_assign: unknown attribute %d", vp->type); return -1; } return 0; }
MediaParser *mparser_find(const char *encoding_name) { int i; for(i=0; media_parsers[i]; i++) { if ( !g_ascii_strcasecmp(encoding_name, media_parsers[i]->info->encoding_name) ) { rc_log(RC_LOG_DEBUG, "[MT] Found Media Parser for %s\n", encoding_name); return media_parsers[i]; } } rc_log(RC_LOG_DEBUG, "[MT] Media Parser for %s not found\n", encoding_name); return NULL; }
/** Initialise a configuration structure * * Initialize the configuration structure from an external program. For use when not * running a standalone client that reads from a config file. * * @param rh a handle to parsed configuration. * @return rc_handle on success, NULL on failure. */ rc_handle *rc_config_init(rc_handle *rh) { int i; SERVER *authservers; SERVER *acctservers; OPTION *acct; OPTION *auth; rh->config_options = malloc(sizeof(config_options_default)); if (rh->config_options == NULL) { rc_log(LOG_CRIT, "rc_config_init: out of memory"); rc_destroy(rh); return NULL; } memcpy(rh->config_options, &config_options_default, sizeof(config_options_default)); acct = find_option(rh, "acctserver", OT_ANY); auth = find_option(rh, "authserver", OT_ANY); authservers = malloc(sizeof(SERVER)); acctservers = malloc(sizeof(SERVER)); if(authservers == NULL || acctservers == NULL) { rc_log(LOG_CRIT, "rc_config_init: error initializing server structs"); rc_destroy(rh); if(authservers) free(authservers); if(acctservers) free(acctservers); return NULL; } authservers->max = 0; acctservers->max = 0; for(i=0; i < SERVER_MAX; i++) { authservers->name[i] = NULL; authservers->secret[i] = NULL; acctservers->name[i] = NULL; acctservers->secret[i] = NULL; } acct->val = acctservers; auth->val = authservers; return rh; }
/** Get the value of a config option * * @param rh a handle to parsed configuration. * @param optname the name of an option. * @return config option value. */ int rc_conf_int(rc_handle const *rh, char const *optname) { OPTION *option; option = find_option(rh, optname, OT_INT|OT_AUO); if (option != NULL) { if (option->val) { return *((int *)option->val); } else { rc_log(LOG_ERR, "rc_conf_int: config option %s was not set", optname); return 0; } } else { rc_log(LOG_CRIT, "rc_conf_int: unkown config option requested: %s", optname); return 0; } }
LFUNC auth_local(char *username, char *passwd) { struct passwd *pw; char *xpasswd; #ifdef SHADOW_PASSWORD struct spwd *spw; #endif if ((pw = getpwnam(username)) == NULL) { endpwent(); rc_log(LOG_NOTICE, "authentication FAILED, type local, username %s", username); printf(SC_LOCAL_FAILED); return NULL; } endpwent(); #ifdef SHADOW_PASSWORD if((spw = getspnam(pw->pw_name)) == NULL) { endspent(); rc_log(LOG_NOTICE, "authentication FAILED, type local, username %s", username); printf(SC_LOCAL_FAILED); return NULL; } else { pw->pw_passwd = spw->sp_pwdp; } endspent(); #endif /* SHADOW_PASSWORD */ xpasswd = crypt(passwd, pw->pw_passwd); if (*pw->pw_passwd == '\0' || strcmp(xpasswd, pw->pw_passwd)) { rc_log(LOG_NOTICE, "authentication FAILED, type local, username %s", username); printf(SC_LOCAL_FAILED); return NULL; } rc_log(LOG_NOTICE, "authentication OK, type local, username %s", username); printf(SC_LOCAL_OK); return local_login; }
static __inline__ void rtp_session_resume_live(RTP_session *rtp_s) { GEvent *ev; if (rtp_s->playing) return; if (pipe2(rtp_s->fd, O_NONBLOCK) < 0) { rc_log( RC_LOG_ERR, "[RTP] play live stream faild, pipe() < 0, err:%d.", errno ); rtp_s->fd[0] = -1; rtp_s->fd[1] = -1; return; } if (G_UNLIKELY(rtp_s->transport.rtp_writer)) /* BUG */ { rc_log( RC_LOG_ERR, "[RTP] play live stream faild, 'rtp_s->transport.rtp_writer' exists." ); rtp_s->playing = TRUE; return; } ev = g_event_new(sizeof(RTP_writer), rtp_s->fd[0], EV_READ); g_event_set_timeout(ev, 100); g_event_set_callback(ev, rtp_lwrite_cb, rtp_s, on_rtp_writer_destroy); ((RTP_writer*)ev)->rtp_s = rtp_s; rtp_s->transport.rtp_writer = ev; rtp_session_ref(rtp_s); bq_producer_add_fd(rtp_s->track->producer, rtp_s->fd[1], NULL, on_producer_working, NULL); g_scheduler_add(ev, LOOP_WEIGHT_VIDEO); rtp_s->playing = TRUE; }
static int set_option_auo(char *filename, int line, OPTION *option, char *p) { int *iptr; if (p == NULL) { rc_log(LOG_WARNING, "%s: line %d: bogus option value", filename, line); return (-1); } if ((iptr = (int *) malloc(sizeof(iptr))) == NULL) { rc_log(LOG_CRIT, "read_config: out of memory"); return (-1); } *iptr = 0; p = strtok(p, ", \t"); if (!strncmp(p, "local", 5)) *iptr = AUTH_LOCAL_FST; else if (!strncmp(p, "radius", 6)) *iptr = AUTH_RADIUS_FST; else { rc_log(LOG_ERR,"%s: auth_order: unknown keyword: %s", filename, p); return (-1); } p = strtok(NULL, ", \t"); if (p && (*p != '\0')) { if ((*iptr & AUTH_RADIUS_FST) && !strcmp(p, "local")) *iptr = (*iptr) | AUTH_LOCAL_SND; else if ((*iptr & AUTH_LOCAL_FST) && !strcmp(p, "radius")) *iptr = (*iptr) | AUTH_RADIUS_SND; else { rc_log(LOG_ERR,"%s: auth_order: unknown or unexpected keyword: %s", filename, p); return (-1); } } option->val = (void *) iptr; return 0; }
static int set_option_int(const char *filename, int line, OPTION *option, const char *p) { int *iptr; if (p == NULL) { rc_log(LOG_ERR, "%s: line %d: bogus option value", filename, line); return -1; } if ((iptr = malloc(sizeof(*iptr))) == NULL) { rc_log(LOG_CRIT, "read_config: out of memory"); return -1; } *iptr = atoi(p); option->val = (void *) iptr; return 0; }
int rc_add_config(rc_handle *rh, const char *option_name, const char *option_val, const char *source, const int line) { OPTION *option; if ((option = find_option(rh, option_name, OT_ANY)) == NULL) { rc_log(LOG_ERR, "ERROR: unrecognized option: %s", option_name); return -1; } if (option->status != ST_UNDEF) { rc_log(LOG_ERR, "ERROR: duplicate option: %s", option_name); return -1; } switch (option->type) { case OT_STR: if (set_option_str(source, line, option, option_val) < 0) { return -1; } break; case OT_INT: if (set_option_int(source, line, option, option_val) < 0) { return -1; } break; case OT_SRV: if (set_option_srv(source, line, option, option_val) < 0) { return -1; } break; case OT_AUO: if (set_option_auo(source, line, option, option_val) < 0) { return -1; } break; default: rc_log(LOG_CRIT, "rc_read_config: impossible case branch!"); abort(); } return 0; }
/** Initialises new Radius Client handle * * @return a new rc_handle (free with rc_destroy). */ rc_handle *rc_new(void) { rc_handle *rh; rh = calloc(1, sizeof(*rh)); if (rh == NULL) { rc_log(LOG_CRIT, "rc_new: out of memory"); return NULL; } return rh; }
/** Tests the configuration the user supplied * * @param rh a handle to parsed configuration. * @param filename a name of a configuration file. * @return 0 on success, -1 when failure. */ int rc_test_config(rc_handle *rh, char const *filename) { SERVER *srv; srv = rc_conf_srv(rh, "authserver"); if (!srv || !srv->max) { rc_log(LOG_ERR,"%s: no authserver specified", filename); return -1; } srv = rc_conf_srv(rh, "acctserver"); if (!srv || !srv->max) { /* it is allowed not to have acct servers */ if (rh->so_type != RC_SOCKET_TLS && rh->so_type != RC_SOCKET_DTLS) rc_log(LOG_DEBUG,"%s: no acctserver specified", filename); } if (!rc_conf_str(rh, "dictionary")) { rc_log(LOG_ERR,"%s: no dictionary specified", filename); return -1; } if (rc_conf_int(rh, "radius_timeout") <= 0) { rc_log(LOG_ERR,"%s: radius_timeout <= 0 is illegal", filename); return -1; } if (rc_conf_int(rh, "radius_retries") <= 0) { rc_log(LOG_ERR,"%s: radius_retries <= 0 is illegal", filename); return -1; } if (apply_config(rh) == -1) { return -1; } return 0; }
/** Initialise a configuration structure * * Initialize the configuration structure from an external program. For use when not * running a standalone client that reads from a config file. * * @param rh a handle to parsed configuration. * @return rc_handle on success, NULL on failure. */ rc_handle *rc_config_init(rc_handle *rh) { SERVER *authservers = NULL; SERVER *acctservers; OPTION *acct; OPTION *auth; rh->config_options = malloc(sizeof(config_options_default)); if (rh->config_options == NULL) { rc_log(LOG_CRIT, "rc_config_init: out of memory"); rc_destroy(rh); return NULL; } memcpy(rh->config_options, &config_options_default, sizeof(config_options_default)); auth = find_option(rh, "authserver", OT_ANY); if (auth) { authservers = calloc(1, sizeof(SERVER)); if(authservers == NULL) { rc_log(LOG_CRIT, "rc_config_init: error initializing server structs"); rc_destroy(rh); return NULL; } auth->val = authservers; } acct = find_option(rh, "acctserver", OT_ANY); if (acct) { acctservers = calloc(1, sizeof(SERVER)); if(acctservers == NULL) { rc_log(LOG_CRIT, "rc_config_init: error initializing server structs"); rc_destroy(rh); if(authservers) free(authservers); return NULL; } acct->val = acctservers; } return rh; }
void local_login(rc_handle *rh, char *username) { char *login_local = rc_conf_str(rh, "login_local"); /* login should spot this... but who knows what old /bin/logins * may be still around */ if (*username == '-') { rc_log(LOG_WARNING, "username can't start with a dash"); exit(ERROR_RC); } /* the new shadow login seems to require either a -r or a -h * flag for -f to work (so source code, lmain.c) so we supply * it here. shouldn't hurt on other systems, -lf, 03/13/96 */ execle(login_local, login_local, "-h", "localhost", "-f", username, NULL, env->env); rc_log(LOG_ERR, "couldn't execute %s: %s", login_local, strerror(errno)); sleep(1); /* give the user time to read */ exit(ERROR_RC); }
int rc_avpair_assign (VALUE_PAIR *vp, void *pval, int len) { int result = -1; switch (vp->type) { case PW_TYPE_STRING: if (((len == 0) && (strlen ((char *) pval)) > AUTH_STRING_LEN) || (len > AUTH_STRING_LEN)) { rc_log(LOG_ERR, "rc_avpair_assign: bad attribute length"); return result; } if (len > 0) { memcpy(vp->strvalue, (char *)pval, len); vp->strvalue[len] = '\0'; vp->lvalue = len; } else { strncpy (vp->strvalue, (char *) pval, AUTH_STRING_LEN); vp->lvalue = strlen((char *) pval); } result = 0; break; case PW_TYPE_DATE: case PW_TYPE_INTEGER: case PW_TYPE_IPADDR: vp->lvalue = * (UINT4 *) pval; result = 0; break; default: rc_log(LOG_ERR, "rc_avpair_assign: unknown attribute %d", vp->type); } return result; }
void radius_login(char *username) { char *login_radius = rc_conf_str("login_radius"); execle(login_radius, login_radius, NULL, env->env); rc_log(LOG_ERR, "couldn't execute %s: %s", login_radius, strerror(errno)); fprintf(stderr, "couldn't execute %s: %s", login_radius, strerror(errno)); sleep(1); /* give the user time to read */ exit(ERROR_RC); }
SERVER *rc_conf_srv(char *optname) { OPTION *option; option = find_option(optname, OT_SRV); if (option != NULL) { return (SERVER *)option->val; } else { rc_log(LOG_CRIT, "rc_conf_srv: unkown config option requested: %s", optname); abort(); } }