int chirp_acl_ticket_list(const char *subject, char ***ticket_subjects) { size_t n = 0; *ticket_subjects = NULL; struct chirp_dirent *d; struct chirp_dir *dir; dir = cfs->opendir("/"); if(dir == NULL) return -1; while((d = cfs->readdir(dir))) { if(strcmp(d->name, ".") == 0 || strcmp(d->name, "..") == 0) continue; const char *digest; if(chirp_ticket_isticketfilename(d->name, &digest)) { struct chirp_ticket ct; if(!ticket_read(d->name, &ct)) continue; /* expired? */ if(strcmp(subject, ct.subject) == 0 || strcmp(subject, "all") == 0) { char ticket_subject[CHIRP_PATH_MAX]; n = n + 1; *ticket_subjects = (char **) xxrealloc(*ticket_subjects, (n + 1) * sizeof(char *)); chirp_ticket_subject(ticket_subject, d->name); (*ticket_subjects)[n - 1] = xxstrdup(ticket_subject); (*ticket_subjects)[n] = NULL; } chirp_ticket_free(&ct); } } cfs->closedir(dir); return 0; }
static struct fsm *rebuild_machine(struct fsm *net) { int i,j, group_num, source, target, new_linecount = 0, arccount = 0; struct fsm_state *fsm; struct p *myp; struct e *thise; if (net->statecount == total_states) { return(net); } fsm = net->states; /* We need to make sure state 0 is first in its group */ /* to get the proper numbering of states */ if (E->group->first_e != E) { E->group->first_e = E; } /* Recycling t_count for group numbering use here */ group_num = 1; myp = P; while (myp != NULL) { myp->count = 0; myp = myp->next; } for (i=0; (fsm+i)->state_no != -1; i++) { thise = E+((fsm+i)->state_no); if (thise->group->first_e == thise) { new_linecount++; if ((fsm+i)->start_state == 1) { thise->group->t_count = 0; thise->group->count = 1; } else if (thise->group->count == 0) { thise->group->t_count = group_num++; thise->group->count = 1; } } } for (i=0, j=0; (fsm+i)->state_no != -1; i++) { thise = E+((fsm+i)->state_no); if (thise->group->first_e == thise) { source = thise->group->t_count; target = ((fsm+i)->target == -1) ? -1 : (E+((fsm+i)->target))->group->t_count; add_fsm_arc(fsm, j, source, (fsm+i)->in, (fsm+i)->out, target, finals[(fsm+i)->state_no], (fsm+i)->start_state); arccount = ((fsm+i)->target == -1) ? arccount : arccount+1; j++; } } add_fsm_arc(fsm, j, -1, -1, -1, -1, -1, -1); fsm = xxrealloc(fsm,sizeof(struct fsm_state)*(new_linecount+1)); net->states = fsm; net->linecount = j+1; net->arccount = arccount; net->statecount = total_states; return(net); }
char *path_getcwd (void) { char *result = NULL; size_t size = PATH_MAX; result = xxrealloc(result, size); while(getcwd(result, size) == NULL) { if(errno == ERANGE) { size *= 2; result = xxrealloc(result, size); } else { fatal("couldn't getcwd: %s", strerror(errno)); return NULL; } } return result; }
int auth_ticket_register(void) { if(!client_tickets) { client_tickets = xxrealloc(NULL, sizeof(char *)); client_tickets[0] = NULL; } debug(D_AUTH, "ticket: registered"); return auth_register("ticket", auth_ticket_assert, auth_ticket_accept); }
int chirp_acl_ticket_modify(const char *subject, const char *ticket_subject, const char *path, int flags) { char ticket_filename[CHIRP_PATH_MAX]; const char *digest; char *esubject; struct chirp_ticket ct; int status = 0; if(!chirp_ticket_isticketsubject(ticket_subject, &digest)) { errno = EINVAL; return -1; } /* Note about tickets making tickets: * We check whether the ticket has the rights associated with the mask in * the next line. So, a ticket can only make a ticket with rights it * already has. */ if(!chirp_acl_check_dir(path, subject, flags)) return -1; /* you don't have the rights for the mask */ if(!chirp_acl_whoami(subject, &esubject)) return -1; chirp_ticket_filename(ticket_filename, ticket_subject, NULL); if(!ticket_read(ticket_filename, &ct)) { free(esubject); return -1; } if(strcmp(esubject, ct.subject) == 0 || strcmp(chirp_super_user, subject) == 0) { size_t n; int replaced = 0; for(n = 0; n < ct.nrights; n++) { if(strcmp(ct.rights[n].directory, path) == 0) { free(ct.rights[n].acl); ct.rights[n].acl = xxstrdup(chirp_acl_flags_to_text(flags)); /* replace old acl mask */ replaced = 1; } } if(!replaced) { char directory[CHIRP_PATH_MAX]; assert(strlen(path)); ct.rights = xxrealloc(ct.rights, sizeof(*ct.rights) * (++ct.nrights) + 1); path_collapse(path, directory, 1); ct.rights[ct.nrights - 1].directory = xxstrdup(directory); ct.rights[ct.nrights - 1].acl = xxstrdup(chirp_acl_flags_to_text(flags)); } status = ticket_write(ticket_filename, &ct); } else { errno = EACCES; status = -1; } chirp_ticket_free(&ct); free(esubject); return status; }
static unsigned int move_set(int *set, int setsize) { unsigned int old_offset; if (set_table_offset + setsize >= set_table_size) { while (set_table_offset + setsize >= set_table_size) { set_table_size *= 2; } set_table = xxrealloc(set_table, set_table_size * sizeof(int)); } memcpy(set_table+set_table_offset, set, setsize * sizeof(int)); old_offset = set_table_offset; set_table_offset += setsize; return(old_offset); }
void auth_ticket_load(const char *tickets) { size_t n = 0; client_tickets = xxrealloc(client_tickets, sizeof(char *)); client_tickets[n] = NULL; if(tickets) { const char *start, *end; for(start = end = tickets; start < tickets + strlen(tickets); start = ++end) { while(*end != '\0' && *end != ',') end++; if(start == end) continue; char *value = xxmalloc(end - start + 1); memset(value, 0, end - start + 1); strncpy(value, start, end - start); debug(D_CHIRP, "adding %s", value); client_tickets = xxrealloc(client_tickets, sizeof(char *) * ((++n) + 1)); client_tickets[n - 1] = value; client_tickets[n] = NULL; } } else { /* populate a list with tickets in the current directory */ int i; char **list; sort_dir(".", &list, strcmp); for(i = 0; list[i]; i++) { if(strncmp(list[i], "ticket.", strlen("ticket.")) == 0 && (strlen(list[i]) == (strlen("ticket.") + (MD5_DIGEST_LENGTH << 1)))) { debug(D_CHIRP, "adding ticket %s", list[i]); client_tickets = xxrealloc(client_tickets, sizeof(char *) * ((++n) + 1)); client_tickets[n - 1] = strdup(list[i]); client_tickets[n] = NULL; } } sort_dir_free(list); } }
void fsm_state_add_arc(int state_no, int in, int out, int target, int final_state, int start_state) { struct fsm_state *cptr; if (in != out) { arity = 2; } /* Check epsilon moves */ if (in == EPSILON && out == EPSILON) { if (state_no == target) { return; } else { is_deterministic = 0; is_epsilon_free = 0; } } /* Check if we already added this particular arc and skip */ /* Also check if net becomes non-det */ if (in != -1 && out != -1) { if ((slookup+(ssize*in)+out)->mainloop == mainloop) { if ((slookup+(ssize*in)+out)->target == target) { return; } else { is_deterministic = 0; } } arccount++; (slookup+(ssize*in)+out)->mainloop = mainloop; (slookup+(ssize*in)+out)->target = target; } current_trans = 1; if (current_fsm_linecount >= current_fsm_size) { current_fsm_size *= 2; current_fsm_head = xxrealloc(current_fsm_head, current_fsm_size * sizeof(struct fsm_state)); if (current_fsm_head == NULL) { perror("Fatal error: out of memory\n"); exit(1); } } cptr = current_fsm_head + current_fsm_linecount; cptr->state_no = state_no; cptr->in = in; cptr->out = out; cptr->target = target; cptr->final_state = final_state; cptr->start_state = start_state; current_fsm_linecount++; }
int fsm_construct_add_symbol(struct fsm_construct_handle *handle, char *symbol) { int i, symnum, reserved; unsigned int hash; struct fsm_sigma_hash *fh, *newfh; char *symdup; /* Is symbol reserved? */ for (i=0, reserved = 0; foma_reserved_symbols[i].symbol != NULL; i++) { if (strcmp(symbol, foma_reserved_symbols[i].symbol) == 0) { symnum = foma_reserved_symbols[i].number; reserved = 1; if (handle->maxsigma < symnum) { handle->maxsigma = symnum; } break; } } if (reserved == 0) { symnum = handle->maxsigma + 1; if (symnum < MINSIGMA) symnum = MINSIGMA; handle->maxsigma = symnum; } if (symnum >= handle->fsm_sigma_list_size) { handle->fsm_sigma_list_size = next_power_of_two(handle->fsm_sigma_list_size); handle->fsm_sigma_list = xxrealloc(handle->fsm_sigma_list, (handle->fsm_sigma_list_size) * sizeof(struct fsm_sigma_list)); } /* Insert into list */ symdup = xxstrdup(symbol); ((handle->fsm_sigma_list)+symnum)->symbol = symdup; /* Insert into hashtable */ hash = fsm_construct_hash_sym(symbol); fh = (handle->fsm_sigma_hash)+hash; if (fh->symbol == NULL) { fh->symbol = symdup; fh->sym = symnum; } else { newfh = xxcalloc(1,sizeof(struct fsm_sigma_hash)); newfh->next = fh->next; fh->next = newfh; newfh->symbol = symdup; newfh->sym = symnum; } return symnum; }
INT64_T chirp_client_ticket_list(struct chirp_client * c, const char *subject, char ***list, time_t stoptime) { INT64_T result; size_t size = 0; *list = NULL; result = simple_command(c, stoptime, "ticket_list %s\n", subject); if(result == 0) { while(1) { char line[CHIRP_LINE_MAX]; size_t length; if(!link_readline(c->link, line, CHIRP_LINE_MAX, stoptime)) goto failure; if(sscanf(line, "%zu", &length) != 1) goto failure; if(length == 0) break; size++; *list = xxrealloc(*list, sizeof(char *) * (size + 1)); (*list)[size - 1] = xxmalloc(sizeof(char) * (length + 1)); if(!link_read(c->link, (*list)[size - 1], length, stoptime)) goto failure; (*list)[size - 1][length] = '\0'; (*list)[size] = NULL; } return 0; failure: if(*list != NULL) { char **tmp = *list; while(tmp[0]) { free(tmp[0]); } free(*list); } c->broken = 1; errno = ECONNRESET; return -1; } return result; }
void add_T_ptr(int setnum, int setsize, unsigned int theset, int fs) { int i; if (setnum >= T_limit) { T_limit *= 2; T_ptr = xxrealloc(T_ptr, sizeof(struct T_memo)*T_limit); for (i=setnum; i < T_limit; i++) { (T_ptr+i)->size = 0; } } (T_ptr + setnum)->size = setsize; (T_ptr + setnum)->set_offset = theset; (T_ptr + setnum)->finalstart = fs; int_stack_push(setnum); }
static void apply_stack_push (struct apply_handle *h, int sptr, int sipos, int sopos, int vmark, char *sflagname, char *sflagvalue, int sflagneg) { if (h->apply_stack_ptr == h->apply_stack_top) { h->searchstack = xxrealloc(h->searchstack, sizeof(struct searchstack)* ((h->apply_stack_top)*2)); if (h->searchstack == NULL) { perror("Apply stack full!!!\n"); exit(0); } h->apply_stack_top *= 2; } (h->searchstack+h->apply_stack_ptr)->offset = sptr; (h->searchstack+h->apply_stack_ptr)->ipos = sipos; (h->searchstack+h->apply_stack_ptr)->opos = sopos; (h->searchstack+h->apply_stack_ptr)->visitmark = vmark; (h->searchstack+h->apply_stack_ptr)->flagname = sflagname; (h->searchstack+h->apply_stack_ptr)->flagvalue = sflagvalue; (h->searchstack+h->apply_stack_ptr)->flagneg = sflagneg; (h->apply_stack_ptr)++; }
void fsm_construct_check_size(struct fsm_construct_handle *handle, int state_no) { int i, oldsize, newsize; struct fsm_state_list *sl; oldsize = handle->fsm_state_list_size; if (oldsize <= state_no) { newsize = next_power_of_two(state_no); handle->fsm_state_list = xxrealloc(handle->fsm_state_list, newsize*sizeof(struct fsm_state_list)); handle->fsm_state_list_size = newsize; sl = handle->fsm_state_list; for (i=oldsize; i<newsize;i++) { (sl+i)->is_final = 0; (sl+i)->is_initial = 0; (sl+i)->used = 0; (sl+i)->num_trans = 0; (sl+i)->fsm_trans_list = NULL; } } }
void fsm_trie_symbol(struct fsm_trie_handle *th, char *insym, char *outsym) { unsigned int h; struct trie_hash *thash, *newthash; h = trie_hashf(th->trie_cursor, insym, outsym); if ((th->trie_hash+h)->insym != NULL) { for (thash = th->trie_hash+h; thash != NULL; thash = thash->next) { if (strcmp(thash->insym, insym) == 0 && strcmp(thash->outsym, outsym) == 0 && thash->sourcestate == th->trie_cursor) { /* Exists, move cursor */ th->trie_cursor = thash->targetstate; return; } } } /* Doesn't exist */ /* Insert trans, move counter and cursor */ th->used_states++; thash = th->trie_hash+h; if (thash->insym == NULL) { thash->insym = sh_find_add_string(th->sh_hash, insym,1); thash->outsym = sh_find_add_string(th->sh_hash, outsym,1); thash->sourcestate = th->trie_cursor; thash->targetstate = th->used_states; } else { newthash = xxcalloc(1, sizeof(struct trie_hash)); newthash->next = thash->next; newthash->insym = sh_find_add_string(th->sh_hash, insym,1); newthash->outsym = sh_find_add_string(th->sh_hash, outsym,1); newthash->sourcestate = th->trie_cursor; newthash->targetstate = th->used_states; thash->next = newthash; } th->trie_cursor = th->used_states; /* Realloc */ if (th->used_states >= th->statesize) { th->statesize = next_power_of_two(th->statesize); th->trie_states = xxrealloc(th->trie_states, th->statesize * sizeof(struct trie_states)); } (th->trie_states+th->used_states)->is_final = 0; }
int buffer_vprintf(buffer_t * b, const char *format, va_list va) { va_list va2; size_t osize = b->size; va_copy(va2, va); int n = vsnprintf(NULL, 0, format, va2); va_end(va2); if(n < 0) return -1; b->size += n; b->buf = xxrealloc(b->buf, b->size + 1); /* extra nul byte */ va_copy(va2, va); n = vsnprintf(b->buf + osize, n + 1, format, va2); assert(n >= 0); va_end(va2); return 0; }
void fsm_state_close(struct fsm *net) { fsm_state_add_arc(-1,-1,-1,-1,-1,-1); current_fsm_head = xxrealloc(current_fsm_head, current_fsm_linecount * sizeof(struct fsm_state)); net->arity = arity; net->arccount = arccount; net->statecount = statecount; net->linecount = current_fsm_linecount; net->finalcount = num_finals; net->pathcount = PATHCOUNT_UNKNOWN; if (num_initials > 1) is_deterministic = 0; net->is_deterministic = is_deterministic; net->is_pruned = UNK; net->is_minimized = UNK; net->is_epsilon_free = is_epsilon_free; net->is_loop_free = UNK; net->is_completed = UNK; net->states = current_fsm_head; xxfree(slookup); }
static void apply_stack_push (struct apply_handle *h, int vmark, char *sflagname, char *sflagvalue, int sflagneg) { struct searchstack *ss; if (h->apply_stack_ptr == h->apply_stack_top) { h->searchstack = xxrealloc(h->searchstack, sizeof(struct searchstack)* ((h->apply_stack_top)*2)); if (h->searchstack == NULL) { perror("Apply stack full!!!\n"); exit(0); } h->apply_stack_top *= 2; } ss = h->searchstack+h->apply_stack_ptr; ss->offset = h->curr_ptr; ss->ipos = h->ipos; ss->opos = h->opos; ss->visitmark = vmark; ss->iptr = h->iptr; ss->state_has_index = h->state_has_index; if (h->has_flags) { ss->flagname = sflagname; ss->flagvalue = sflagvalue; ss->flagneg = sflagneg; } (h->apply_stack_ptr)++; }
void fsm_construct_copy_sigma(struct fsm_construct_handle *handle, struct sigma *sigma) { unsigned int hash; int symnum; struct fsm_sigma_hash *fh, *newfh; char *symbol, *symdup; for (; sigma != NULL && sigma->number != -1; sigma = sigma->next) { symnum = sigma->number; if (symnum > handle->maxsigma) { handle->maxsigma = symnum; } symbol = sigma->symbol; if (symnum >= handle->fsm_sigma_list_size) { handle->fsm_sigma_list_size = next_power_of_two(handle->fsm_sigma_list_size); handle->fsm_sigma_list = xxrealloc(handle->fsm_sigma_list, (handle->fsm_sigma_list_size) * sizeof(struct fsm_sigma_list)); } /* Insert into list */ symdup = xxstrdup(symbol); ((handle->fsm_sigma_list)+symnum)->symbol = symdup; /* Insert into hashtable */ hash = fsm_construct_hash_sym(symbol); fh = (handle->fsm_sigma_hash)+hash; if (fh->symbol == NULL) { fh->symbol = symdup; fh->sym = symnum; } else { newfh = xxcalloc(1,sizeof(struct fsm_sigma_hash)); newfh->next = fh->next; fh->next = newfh; newfh->symbol = symdup; newfh->sym = symnum; } } }
int apply_append(struct apply_handle *h, int cptr, int sym) { char *astring, *bstring, *pstring; int symin, symout, len, alen, blen, idlen; symin = (h->gstates+cptr)->in; symout = (h->gstates+cptr)->out; astring = ((h->sigs)+symin)->symbol; alen = ((h->sigs)+symin)->length; bstring = ((h->sigs)+symout)->symbol; blen = ((h->sigs)+symout)->length; while (alen + blen + h->opos + 2 + strlen(h->separator) >= h->outstringtop) { // while (alen + blen + h->opos + 3 >= h->outstringtop) { h->outstring = xxrealloc(h->outstring, sizeof(char) * ((h->outstringtop) * 2)); (h->outstringtop) *= 2; } if ((h->has_flags) && !h->show_flags && (h->flag_lookup+symin)->type) { astring = ""; alen = 0; } if (h->has_flags && !h->show_flags && (h->flag_lookup+symout)->type) { bstring = ""; blen = 0; } if (((h->mode) & ENUMERATE) == ENUMERATE) { /* Print both sides separated by colon */ /* if we're printing "words" */ if (((h->mode) & (UPPER | LOWER)) == (UPPER|LOWER)) { if (astring == bstring) { strcpy(h->outstring+h->opos, astring); len = alen; } else { strcpy(h->outstring+h->opos, astring); // strcpy(h->outstring+h->opos+alen,":"); strcpy(h->outstring+h->opos+alen,h->separator); //strcpy(h->outstring+h->opos+alen+1,bstring); strcpy(h->outstring+h->opos+alen+strlen(h->separator),bstring); // len = alen+blen+1; len = alen+blen+strlen(h->separator); } } /* Print one side only */ if (((h->mode) & (UPPER|LOWER)) != (UPPER|LOWER)) { if (symin == EPSILON) { astring = ""; alen = 0; } if (symout == EPSILON) { bstring = ""; blen = 0; } if (((h->mode) & (UPPER|LOWER)) == UPPER) { pstring = astring; len = alen; } else { pstring = bstring; len = blen; } //strcpy(h->outstring+h->opos, pstring); memcpy(h->outstring+h->opos, pstring, len); } } if (((h->mode) & ENUMERATE) != ENUMERATE) { /* Print pairs is ON and symbols are different */ if (h->print_pairs && (symin != symout)) { if (symin == UNKNOWN && ((h->mode) & DOWN) == DOWN) strncpy(astring, h->instring+h->ipos, 1); if (symout == UNKNOWN && ((h->mode) & UP) == UP) strncpy(bstring, h->instring+h->ipos, 1); strcpy(h->outstring+h->opos, "<"); strcpy(h->outstring+h->opos+1, astring); //strcpy(h->outstring+h->opos+alen+1,":"); strcpy(h->outstring+h->opos+alen+1,h->separator); //strcpy(h->outstring+h->opos+alen+2,bstring); strcpy(h->outstring+h->opos+alen+1+strlen(h->separator), bstring); //strcpy(h->outstring+h->opos+alen+blen+2,">"); strcpy(h->outstring+h->opos+alen+blen+1+strlen(h->separator),">"); //len = alen+blen+3; len = alen+blen+2+strlen(h->separator); } else if (sym == IDENTITY) { /* Apply up/down */ //idlen = utf8skip(h->instring+h->ipos)+1; idlen = (h->sigmatch_array+h->ipos)->consumes; // here strncpy(h->outstring+h->opos, h->instring+h->ipos, idlen); strncpy(h->outstring+h->opos+idlen,"", 1); len = idlen; } else if (sym == EPSILON) { return(0); } else { if (((h->mode) & DOWN) == DOWN) { pstring = bstring; len = blen; } else { pstring = astring; len = alen; } memcpy(h->outstring+h->opos, pstring, len); } } if (h->print_space && len > 0) { strcpy(h->outstring+h->opos+len, h->space_symbol); len++; } return(len); }
struct fsm *flag_twosided(struct fsm *net) { struct fsm_state *fsm; struct sigma *sigma; int i, j, tail, *isflag, maxsigma, maxstate, newarcs, change; /* Enforces twosided flag diacritics */ /* Mark flag symbols */ maxsigma = sigma_max(net->sigma); isflag = xxcalloc(maxsigma+1, sizeof(int)); fsm = net->states; for (sigma = net->sigma ; sigma != NULL; sigma = sigma->next) { if (flag_check(sigma->symbol)) { *(isflag+sigma->number) = 1; } else { *(isflag+sigma->number) = 0; } } maxstate = 0; change = 0; for (i = 0, newarcs = 0; (fsm+i)->state_no != -1 ; i++) { maxstate = (fsm+i)->state_no > maxstate ? (fsm+i)->state_no : maxstate; if ((fsm+i)->target == -1) continue; if (*(isflag+(fsm+i)->in) && (fsm+i)->out == EPSILON) { change = 1; (fsm+i)->out = (fsm+i)->in; } else if (*(isflag+(fsm+i)->out) && (fsm+i)->in == EPSILON) { change = 1; (fsm+i)->in = (fsm+i)->out; } if ((*(isflag+(fsm+i)->in) || *(isflag+(fsm+i)->out)) && (fsm+i)->in != (fsm+i)->out) { newarcs++; } } if (newarcs == 0) { if (change == 1) { net->is_deterministic = UNK; net->is_minimized = UNK; net->is_pruned = UNK; return fsm_topsort(fsm_minimize(net)); } return net; } net->states = xxrealloc(net->states, sizeof(struct fsm)*(i+newarcs)); fsm = net->states; tail = j = i; maxstate++; for (i = 0; i < tail; i++) { if ((fsm+i)->target == -1) continue; if ((*(isflag+(fsm+i)->in) || *(isflag+(fsm+i)->out)) && (fsm+i)->in != (fsm+i)->out) { if (*(isflag+(fsm+i)->in) && !*(isflag+(fsm+i)->out)) { j = add_fsm_arc(fsm, j, maxstate, EPSILON, (fsm+i)->out, (fsm+i)->target, 0, 0); (fsm+i)->out = (fsm+i)->in; (fsm+i)->target = maxstate; maxstate++; } else if (*(isflag+(fsm+i)->out) && !*(isflag+(fsm+i)->in)) { j = add_fsm_arc(fsm, j, maxstate, (fsm+i)->out, (fsm+i)->out, (fsm+i)->target, 0, 0); (fsm+i)->out = EPSILON; (fsm+i)->target = maxstate; maxstate++; } else if (*(isflag+(fsm+i)->in) && *(isflag+(fsm+i)->out)) { j = add_fsm_arc(fsm, j, maxstate, (fsm+i)->out, (fsm+i)->out, (fsm+i)->target, 0, 0); (fsm+i)->out = (fsm+i)->in; (fsm+i)->target = maxstate; maxstate++; } } } /* Add sentinel */ add_fsm_arc(fsm, j, -1, -1, -1, -1, -1, -1); net->is_deterministic = UNK; net->is_minimized = UNK; return fsm_topsort(fsm_minimize(net)); }
int chirp_ticket_read(const char *ticket, struct chirp_ticket *ct) { int status = 0; const char *b = ticket; size_t l = strlen(ticket); /* Ticket format (quoted strings may span multiple lines): * subject "<subject>" * ticket "<ticket>" * expiration "<UTC seconds since Epoch>" * rights "<directory>" "<acl>" * rights "<directory>" "<acl>" * ... */ size_t n; const char *s; const char *buffer = b; time_t now = time(NULL); now = mktime(gmtime(&now)); /* convert to UTC */ ct->subject = NULL; ct->ticket = NULL; ct->expiration = now; /* default expire now... */ ct->expired = 1; /* default is expired */ ct->nrights = 0; ct->rights = NULL; while(1) { assert(buffer >= b && b + l >= buffer); while(unsigned_isspace(*buffer)) buffer++; assert(buffer >= b && b + l >= buffer); if(strncmp(buffer, "subject", strlen("subject")) == 0) { buffer += strlen("subject"); if(!readquote(&buffer, &s, &n)) break; ct->subject = xxrealloc(ct->subject, n + 1); memcpy(ct->subject, s, n); ct->subject[n] = '\0'; } else if(strncmp(buffer, "ticket", strlen("ticket")) == 0) { buffer += strlen("ticket"); if(!readquote(&buffer, &s, &n)) break; ct->ticket = xxrealloc(ct->ticket, n + 1); memcpy(ct->ticket, s, n); ct->ticket[n] = '\0'; } else if(strncmp(buffer, "expiration", strlen("expiration")) == 0) { buffer += strlen("expiration"); if(!readquote(&buffer, &s, &n)) break; char *stime = xxmalloc(n + 1); memcpy(stime, s, n); stime[n] = '\0'; ct->expiration = (time_t) strtoul(stime, NULL, 10); ct->expired = (ct->expiration <= now); free(stime); } else if(strncmp(buffer, "rights", strlen("rights")) == 0) { buffer += strlen("rights"); if(!readquote(&buffer, &s, &n)) break; ct->rights = xxrealloc(ct->rights, sizeof(*ct->rights) * (++ct->nrights) + 1); ct->rights[ct->nrights - 1].directory = xxmalloc(n + 1); memcpy(ct->rights[ct->nrights - 1].directory, s, n); ct->rights[ct->nrights - 1].directory[n] = '\0'; if(!readquote(&buffer, &s, &n)) break; char *acl = xxmalloc(n + 1); memcpy(acl, s, n); acl[n] = '\0'; ct->rights[ct->nrights - 1].acl = xxstrdup(acl); free(acl); } else if(*buffer == '\0') { if(ct->subject && ct->ticket && ct->nrights > 0) { status = 1; } break; } else { break; } } if(ct->rights == NULL) { assert(ct->nrights == 0); ct->rights = xxrealloc(ct->rights, sizeof(*ct->rights) * (++ct->nrights) + 1); ct->rights[ct->nrights - 1].directory = xxstrdup("/"); ct->rights[ct->nrights - 1].acl = xxstrdup("n"); ct->nrights = 1; } return status && !ct->expired; }
INT64_T chirp_client_ticket_get(struct chirp_client * c, const char *name, char **subject, char **ticket, time_t * duration, char ***rights, time_t stoptime) { INT64_T result; char ticket_subject[CHIRP_LINE_MAX]; *subject = *ticket = NULL; *rights = NULL; ticket_translate(name, ticket_subject); result = simple_command(c, stoptime, "ticket_get %s\n", ticket_subject); if(result == 0) { char line[CHIRP_LINE_MAX]; size_t length; size_t nrights = 0; if(!link_readline(c->link, line, CHIRP_LINE_MAX, stoptime)) goto failure; if(sscanf(line, "%zu", &length) != 1) goto failure; *subject = xxmalloc((length + 1) * sizeof(char)); if(!link_read(c->link, *subject, length, stoptime)) goto failure; (*subject)[length] = '\0'; if(!link_readline(c->link, line, CHIRP_LINE_MAX, stoptime)) goto failure; if(sscanf(line, "%zu", &length) != 1) goto failure; *ticket = xxmalloc((length + 1) * sizeof(char)); if(!link_read(c->link, *ticket, length, stoptime)) goto failure; (*ticket)[length] = '\0'; if(!link_readline(c->link, line, CHIRP_LINE_MAX, stoptime)) goto failure; unsigned long long tmp; if(sscanf(line, "%llu", &tmp) != 1) goto failure; *duration = (time_t) tmp; while(1) { char path[CHIRP_PATH_MAX]; char acl[CHIRP_LINE_MAX]; if(!link_readline(c->link, line, CHIRP_LINE_MAX, stoptime)) goto failure; if(sscanf(line, "%s %s", path, acl) == 2) { *rights = xxrealloc(*rights, sizeof(char *) * 2 * (nrights + 2)); (*rights)[nrights * 2 + 0] = xxstrdup(path); (*rights)[nrights * 2 + 1] = xxstrdup(acl); (*rights)[nrights * 2 + 2] = NULL; (*rights)[nrights * 2 + 3] = NULL; nrights++; } else if(sscanf(line, "%" SCNd64 , &result) == 1 && result == 0) { break; } else goto failure; } return 0; failure: free(*subject); free(*ticket); if(*rights != NULL) { char **tmp = *rights; while(tmp[0] && tmp[1]) { free(tmp[0]); free(tmp[1]); } free(*rights); } *subject = *ticket = NULL; c->broken = 1; errno = ECONNRESET; return -1; } return result; }
int apply_append (struct apply_handle *h, int cptr, int sym) { char *astring, *bstring, *pstring; int symin, symout, len, alen, blen; symin = (h->gstates+cptr)->in; symout = (h->gstates+cptr)->out; astring = *((h->sigs)+symin); bstring = *((h->sigs)+symout); if (symin == UNKNOWN) astring = "?"; if (symout == UNKNOWN) bstring = "?"; if (symin == IDENTITY) astring = "@"; if (symout == IDENTITY) bstring = "@"; if (symin == EPSILON) astring = "0"; if (symout == EPSILON) bstring = "0"; alen = strlen(astring); blen = strlen(bstring); while (alen + blen + h->opos + 3 >= h->outstringtop) { h->outstring = xxrealloc(h->outstring, sizeof(char) * ((h->outstringtop) * 2)); (h->outstringtop) *= 2; } if ((h->has_flags) && !g_show_flags && (h->flag_lookup+symin)->type) { astring = ""; alen = 0; } if (h->has_flags && !g_show_flags && (h->flag_lookup+symout)->type) { bstring = ""; blen = 0; } if (((h->mode) & ENUMERATE) == ENUMERATE) { /* Print both sides separated by colon */ /* if we're printing "words" */ if (((h->mode) & (UPPER | LOWER)) == (UPPER|LOWER)) { if (astring == bstring) { strcpy(h->outstring+h->opos, astring); len = alen; } else { strcpy(h->outstring+h->opos, astring); strcpy(h->outstring+h->opos+alen,":"); strcpy(h->outstring+h->opos+alen+1,bstring); len = alen+blen+1; } } /* Print one side only */ if (((h->mode) & (UPPER|LOWER)) != (UPPER|LOWER)) { if (symin == EPSILON) { astring = ""; alen = 0; } if (symout == EPSILON) { bstring = ""; blen = 0; } if (((h->mode) & (UPPER|LOWER)) == UPPER) { pstring = astring; len = alen; } else { pstring = bstring; len = blen; } strcpy(h->outstring+h->opos, pstring); } } if (((h->mode) & ENUMERATE) != ENUMERATE) { /* Print pairs is ON and symbols are different */ if (g_print_pairs && (symin != symout)) { if (symin == UNKNOWN && ((h->mode) & DOWN) == DOWN) strncpy(astring, h->instring+h->ipos, 1); if (symout == UNKNOWN && ((h->mode) & UP) == UP) strncpy(bstring, h->instring+h->ipos, 1); strcpy(h->outstring+h->opos, "<"); strcpy(h->outstring+h->opos+1, astring); strcpy(h->outstring+h->opos+alen+1,":"); strcpy(h->outstring+h->opos+alen+2,bstring); strcpy(h->outstring+h->opos+alen+blen+2,">"); len = alen+blen+3; } else if (sym == IDENTITY) { /* Apply up/down */ strncpy(h->outstring+h->opos, h->instring+h->ipos, 1); strncpy(h->outstring+h->opos+1,"", 1); len = 1; } else if (sym == EPSILON) { return(0); } else { if (((h->mode) & DOWN) == DOWN) { pstring = bstring; len = blen; } else { pstring = astring; len = alen; } strcpy(h->outstring+h->opos, pstring); } } if (g_print_space && len > 0) { strcpy(h->outstring+h->opos+len, " "); len++; } return(len); }
INT64_T chirp_client_ticket_register(struct chirp_client * c, const char *name, const char *subject, time_t duration, time_t stoptime) { char command[PATH_MAX * 2 + 4096]; char ticket_subject[CHIRP_LINE_MAX]; FILE *shell; int status; if(access(name, R_OK) != 0) return -1; /* the 'name' argument must be a client ticket filename */ ticket_translate(name, ticket_subject); /* BEWARE: we don't bother to escape the filename, a user could * provide a malicious filename that makes us execute code we don't want to. */ sprintf(command, "if [ -r '%s' ]; then sed '/^\\s*#/d' < '%s' | openssl rsa -pubout 2> /dev/null; exit 0; else exit 1; fi", name, name); shell = popen(command, "r"); if(!shell) return -1; /* read the ticket file (public key) */ char *ticket = xxrealloc(NULL, 4096); size_t read, length = 0; while((read = fread(ticket + length, 1, 4096, shell)) > 0) { length += read; ticket = xxrealloc(ticket, length + 4096); } if(ferror(shell)) { status = pclose(shell); errno = ferror(shell); return -1; } assert(feof(shell)); status = pclose(shell); if(status) { errno = EINVAL; return -1; } if(subject == NULL) subject = "self"; INT64_T result = send_command(c, stoptime, "ticket_register %s %llu %zu\n", subject, (unsigned long long) duration, length); if(result < 0) { free(ticket); return result; } result = link_write(c->link, ticket, length, stoptime); free(ticket); if(result != (int) length) { c->broken = 1; errno = ECONNRESET; return -1; } result = get_result(c, stoptime); if(result == 0) { time_t t; struct tm tm; char now[1024]; char expiration[1024]; time(&t); localtime_r(&t, &tm); my_strftime(now, sizeof(now) / sizeof(char), "%c", &tm); t += duration; localtime_r(&t, &tm); my_strftime(expiration, sizeof(expiration) / sizeof(char), "%c", &tm); FILE *file = fopen(name, "a"); if(file == NULL) return -1; fprintf(file, "# %s: Registered with %s as \"%s\". Expires on %s\n", now, c->hostport, subject, expiration); fclose(file); } return result; }