static inline int ftrigio_read (ftrigio_t *p) { unsigned int i = FTRIGRD_MAXREADS ; while (i--) { regmatch_t pmatch ; unsigned int blen ; register int r = sanitize_read(buffer_fill(&p->b)) ; if (!r) break ; if (r < 0) return (trig(p->id, 'd', errno), 0) ; blen = buffer_len(&p->b) ; if (!stralloc_readyplus(&p->sa, blen+1)) dienomem() ; buffer_getnofill(&p->b, p->sa.s + p->sa.len, blen) ; p->sa.len += blen ; p->sa.s[p->sa.len] = 0 ; while (!regexec(&p->re, p->sa.s, 1, &pmatch, REG_NOTBOL | REG_NOTEOL)) { trig(p->id, '!', p->sa.s[pmatch.rm_eo - 1]) ; if (!(p->options & FTRIGR_REPEAT)) return 0 ; byte_copy(p->sa.s, p->sa.len + 1 - pmatch.rm_eo, p->sa.s + pmatch.rm_eo) ; p->sa.len -= pmatch.rm_eo ; } } return 1 ; }
extern char* stralloc_cstr( stralloc_t* s ) { stralloc_readyplus( s, 1 ); s->s[s->n] = 0; return s->s; }
extern void stralloc_append( stralloc_t* s, stralloc_t* from ) { stralloc_readyplus( s, from->n ); memcpy( s->s + s->n, from->s, from->n ); s->n += from->n; }
extern void stralloc_add_bytes( stralloc_t* s, const void* from, unsigned len ) { stralloc_readyplus( s, len ); memcpy( s->s + s->n, from, len ); s->n += len; }
/* stralloc_catb adds the string buf[0], buf[1], ... buf[len-1] to the * end of the string stored in sa, allocating space if necessary, and * returns 1. If sa is unallocated, stralloc_catb is the same as * stralloc_copyb. If it runs out of memory, stralloc_catb leaves sa * alone and returns 0. */ int stralloc_catb(stralloc *sa,const char *buf,size_t len) { if (stralloc_readyplus(sa,len)) { byte_copy(sa->s+sa->len,len,buf); sa->len+=len; return 1; } return 0; }
int fmt_to_sa(size_t (*func)(char*, const char*, size_t), stralloc* sa, const char* src, size_t len) { size_t needed = func(0, src, len); if(!stralloc_readyplus(sa, needed)) return 0; func(sa->s + sa->len, src, len); sa->len += needed; return needed; }
unsigned long scan_to_sa(unsigned long (*func)(const char*,char*,unsigned long*), const char* src,stralloc* sa) { unsigned long written; unsigned long r; if (!stralloc_readyplus(sa,str_len(src))) return 0; if ((r=func(src,sa->s+sa->len,&written))) sa->len+=written; return r; }
size_t scan_to_sa(size_t (*func)(const char*,char*,size_t*), const char* src,stralloc* sa) { size_t written; size_t r; if (!stralloc_readyplus(sa,str_len(src))) return 0; if ((r=func(src,sa->s+sa->len,&written))) sa->len+=written; return r; }
/* stralloc_catb adds the string buf[0], buf[1], ... buf[len - 1] to the * end of the string stored in sa, allocating space if necessary, and * returns len. If sa is unallocated, stralloc_catb is the same as * stralloc_copyb. If it runs out of memory, stralloc_catb leaves sa * alone and returns 0. */ int stralloc_write(int fd, const char* buf, size_t len, buffer* b) { stralloc* sa = (stralloc*)b->cookie; if(stralloc_readyplus(sa, len)) { byte_copy(sa->s + sa->len, len, buf); sa->len += len; return len; } return 0; }
int stralloc_catlong0(stralloc *sa, signed long int in, unsigned long n) { int neg = -(in < 0); if(neg) in = -in; if(stralloc_readyplus(sa, fmt_minus(0, neg) + fmt_ulong0(0, (unsigned long)in, n))) { sa->len += fmt_minus(sa->s + sa->len, neg); sa->len += fmt_ulong0(sa->s + sa->len, (unsigned long)in, n); return 1; } else return 0; }
static int doit(stralloc *out,stralloc *fqdn) { unsigned int i; char code; char ch; char ip[16]; if (!stralloc_copys(out,"")) return -1; if (!stralloc_readyplus(fqdn,1)) return -1; fqdn->s[fqdn->len]=0; if ((i=ip6_scan(fqdn->s,ip))) { if (!fqdn->s[i]) { stralloc_copyb(out,ip,16); return 0; } } if ((i=ip4_scan(fqdn->s,ip+12))) { if (!fqdn->s[i]) { byte_zero(ip,10); ip[10]=ip[11]=0xff; stralloc_copyb(out,ip,16); return 0; } } code = 0; for (i = 0;i <= fqdn->len;++i) { if (i < fqdn->len) ch = fqdn->s[i]; else ch = '.'; if ((ch == '[') || (ch == ']')) continue; if (ch == '.') { if (!stralloc_append(out,&code)) return -1; code = 0; continue; } if ((ch >= '0') && (ch <= '9')) { code *= 10; code += ch - '0'; continue; } if (!dns_domain_fromdot(&q,fqdn->s,fqdn->len)) return -1; if (dns_resolve(q,DNS_T_AAAA) == -1) return -1; if (dns_ip6_packet(out,dns_resolve_tx.packet,dns_resolve_tx.packetlen) == -1) return -1; dns_transmit_free(&dns_resolve_tx); dns_domain_free(&q); return 0; } out->len &= ~3; return 0; }
size_t stralloc_scan(stralloc* out, const stralloc* in, size_t (*scan_function)(const char*, char*)) { size_t i; stralloc_zero(out); for(i = 0; i < in->len; ++out->len) { if(!stralloc_readyplus(out, 1)) return 0; i += scan_function(&in->s[i], &out->s[out->len]); } return out->len; }
int readclose_append(int fd,stralloc *sa,unsigned int bufsize) { int r; for (;;) { if (!stralloc_readyplus(sa,bufsize)) { close(fd); return -1; } r = read(fd,sa->s + sa->len,bufsize); if (r == -1) if (errno == error_intr) continue; if (r <= 0) { close(fd); return r; } sa->len += r; } }
static ssize_t strallocwrite(int fd,char* buf,size_t len,void* myself) { buffer* b=myself; stralloc* sa=b->cookie; sa->len+=len; if (stralloc_readyplus(sa,1024)==0) return 0; b->x=sa->s+sa->len; b->p=0; b->a=1024; (void)fd; (void)buf; return len; }
size_t stralloc_fmt(stralloc* out, const char* in, size_t in_len, size_t (*fmt_function)()) { size_t i; stralloc_zero(out); for(i = 0; i < in_len; ++i) { if(!stralloc_readyplus(out, 10)) return 0; out->len += fmt_function(&out->s[out->len], in[i]); } stralloc_trunc(out, out->len); return out->len; }
extern void stralloc_add_hexdump( stralloc_t* s, void* base, int size, const char* prefix ) { uint8_t* p = (uint8_t*)base; const int max_count = 16; int prefix_len = strlen(prefix); while (size > 0) { int count = size > max_count ? max_count : size; int count2; int n; stralloc_add_bytes( s, prefix, prefix_len ); stralloc_add_hex( s, p[0], 2 ); for (n = 1; n < count; n++) { stralloc_add_c( s, ' ' ); stralloc_add_hex( s, p[n], 2 ); } count2 = 4 + 3*(max_count - count); stralloc_readyplus( s, count2 ); memset( s->s + s->n, ' ', count2 ); s->n += count2; stralloc_readyplus(s, count+1); for (n = 0; n < count; n++) { int c = p[n]; if (c < 32 || c > 127) c = '.'; s->s[s->n++] = c; } s->s[s->n++] = '\n'; size -= count; p += count; } }
int rijndaelEncrypt_cbc(char *p, unsigned int l, stralloc *c) { unsigned int n; if(l % 16 != 0) /* XXX */ strerr_die2sys(111, FATAL, "input data is not 128 Bit aligned"); /* fill the IV */ stralloc_readyplus(c, 16); blockMT(&c->s[c->len], 16); c->len += 16; for(n = 0; n < l; n += 16) { stralloc_readyplus(c, 16); byte_xor(&p[n], &c->s[c->len-16], &c->s[c->len], 16); rijndaelEncrypt(&c->s[c->len]); c->len += 16; } return c->len; }
int stralloc_catb(stralloc *r, const void *xv, long long xlen) { const unsigned char *x = xv; long long i; if (!r || !xv || xlen < 0) { errno = EINVAL; return 0; } if (xlen == 0) return 1; if (!stralloc_readyplus(r, xlen)) return 0; for (i = 0; i < xlen; ++i) r->s[r->len + i] = x[i]; r->len += xlen; return 1; }
int stralloc_catv (stralloc *sa, siovec_t const *v, unsigned int n) { register unsigned int i = 0 ; { unsigned int total = 0 ; for (; i < n ; i++) total += v[i].len ; if (!stralloc_readyplus(sa, total)) return 0 ; } for (i = 0 ; i < n ; i++) { byte_copy(sa->s + sa->len, v[i].len, v[i].s) ; sa->len += v[i].len ; } return 1 ; }
void iso2txt(char *s, int len, stralloc *sa) { unsigned char *c; for(c = s; c < s + len; c++) { if(*c > 127 || *c < 32 || *c == '\\' || *c == ',') { stralloc_append(sa, "\\"); stralloc_readyplus(sa, 3); sa->s[sa->len++] = ((*c & 0xc0) >> 6) + '0'; sa->s[sa->len++] = ((*c & 0x38) >> 3) + '0'; sa->s[sa->len++] = (*c & 0x07) + '0'; } else
int vbaprintf (bufalloc *ba, char const *format, va_list args) { int r ; { va_list ugly ; va_copy(ugly, args) ; r = vsnprintf(0, 0, format, ugly) ; va_end(ugly) ; } if (r < 0) return r ; if (!stralloc_readyplus(&ba->x, (unsigned int)r + 1)) return -1 ; r = vsnprintf(ba->x.s + ba->x.len, (unsigned int)r + 1, format, args) ; if (r > 0) ba->x.len += r ; return r ; }
int call_getln(substdio *ss, stralloc *l) { int i; if (!stralloc_copys(l, "")) return -1; for (;;) { if (!stralloc_readyplus(l,1)) return -1; i = substdio_get(ss, l->s + l->len, 1); if (i != 1) return i; if (l->s[l->len] == '\n') break; ++l->len; } if (l->len > 0) if (l->s[l->len-1] == '\r') --l->len; l->s[l->len] = 0; return l->len; }
extern void stralloc_add_hex( stralloc_t* s, unsigned value, int num_digits ) { const char hexdigits[16] = "0123456789abcdef"; int nn; if (num_digits <= 0) return; stralloc_readyplus(s, num_digits); for (nn = num_digits-1; nn >= 0; nn--) { s->s[s->n+nn] = hexdigits[value & 15]; value >>= 4; } s->n += num_digits; }
void stralloc_catulong0(stralloc *sa,unsigned long u,unsigned int n) { unsigned int len; unsigned long q; char *s; len = 1; q = u; while (q > 9) { ++len; q /= 10; } if (len < n) len = n; stralloc_readyplus(sa,len); s = sa->s + sa->len; sa->len += len; while (len) { s[--len] = '0' + (u % 10); u /= 10; } }
char *generate_answer(stralloc *answer, uint32 uid, char *lip, uint16 lport, char *rip, uint16 rport) { char *problem = "ok"; char *x; char buf[5]; stralloc out = {0}; stralloc tmp = {0}; stralloc key = {0}; /* get key from enviroment */ x = env_get("KEY"); if (!x) { problem = "$KEY not set"; strerr_warn1("didentd warning: $KEY not set using 'snakeoilkey'", NULL); x = "snakeoilkey"; } /* initialize rijndael with $KEY */ stralloc_copys(&key, x); txtparse(&key); pad(&key, 32); rijndaelKeySched(6, 8, key.s); /* build answer */ stralloc_cats(answer, " : USERID : OTHER : "); uint32_pack(buf, uid); stralloc_catb(&tmp, buf, 4); uint16_pack(buf, lport); stralloc_catb(&tmp, buf, 2); uint16_pack(buf, rport); stralloc_catb(&tmp, buf, 2); uint32_pack(buf, time(NULL)); stralloc_catb(&tmp, buf, 4); stralloc_catb(&tmp, lip, 4); stralloc_catb(&tmp, rip, 8); /* encrypt last part of answer with rijndael */ rijndaelEncrypt(tmp.s); stralloc_readyplus(&out, 32); base64encode(out.s, tmp.s, 24); stralloc_catb(answer, out.s, 32); stralloc_cats(answer, "\r\n"); stralloc_0(answer); return problem; }
/* * For LDAP, '(', ')', '\', '*' and '\0' have to be escaped with '\'. * We ignore the '\0' case because it is not possible to have a '\0' in s. */ int filter_escape(stralloc *filter, char *s, unsigned int len) { char x; /* pre reserve some space */ if (!stralloc_readyplus(filter, len)) return 0; for (; len != 0; len--) { x = *s++; if (x == '*' || x == '(' || x == ')' || x == '\\') if (!stralloc_append(filter, "\\")) return 0; if (!stralloc_append(filter, &x)) return 0; } return 1; }
int buffer_get_token_sa_pred(buffer* b, stralloc* sa, sa_predicate p, void* arg) { for(;;) { char x; if(!stralloc_readyplus(sa, 1)) return -1; switch(buffer_getc(b, &x)) { case -1: return -1; case 0: return 0; } stralloc_append(sa, &x); switch(p(sa, arg)) { case -1: return -1; case 0: break; case 1: return 0; } } }
int buffer_get_sep_sa( buffer* b, stralloc* sa, const char* sep ) { int i = 0; for (;;) { char x; if ( !stralloc_readyplus(sa, 1 ) ) return -1; switch ( buffer_getc(b, &x) ) { case -1: return -1; case 0: return 0; } i++; stralloc_append(sa, &x); switch ( is_token(sa, sep) ) { case -1: return -1; case 0: break; case 1: return i; } } }
int buffer_get_token_sa(buffer* b,stralloc* sa, const char* charset, size_t setlen) { for (;;) { char x; if (!stralloc_readyplus(sa,1)) goto nomem; switch (buffer_getc(b,&x)) { case -1: return -1; case 0: return 0; } stralloc_append(sa,&x); if (byte_chr(charset,setlen,x)<setlen) break; } return 1; nomem: errno=ENOMEM; return -1; }
int netstring_appendv (stralloc *sa, siovec_t const *v, unsigned int n) { char fmt[UINT_FMT] ; unsigned int len = 0, pos ; register unsigned int i = 0 ; for (; i < n ; i++) len += v[i].len ; pos = uint_fmt(fmt, len) ; if (!stralloc_readyplus(sa, len + pos + 2)) return 0 ; fmt[pos] = ':' ; byte_copy(sa->s + sa->len, pos+1, fmt) ; sa->len += pos+1 ; for (i = 0 ; i < n ; i++) { byte_copy(sa->s + sa->len, v[i].len, v[i].s) ; sa->len += v[i].len ; } sa->s[sa->len++] = ',' ; return 1 ; }