This commit is contained in:
cinap_lenrek 2018-09-25 20:45:11 +02:00
commit e5e6a729dd
13 changed files with 60 additions and 304 deletions

View file

@ -527,6 +527,9 @@ struct NetConnInfo
extern NetConnInfo* getnetconninfo(char*, int);
extern void freenetconninfo(NetConnInfo*);
extern char* idn2utf(char*, char*, int);
extern char* utf2idn(char*, char*, int);
/*
* system calls
*

View file

@ -562,6 +562,7 @@ oservers(uchar *w, int n, Otab *o, Req *r)
static int
odomainlist(uchar *w, int n, Otab *o, Req *q)
{
char val[256];
Ndbtuple *t;
int l, r;
char *s;
@ -570,7 +571,9 @@ odomainlist(uchar *w, int n, Otab *o, Req *q)
for(t = q->t; t != nil; t = t->entry){
if(strcmp(t->attr, o->q[0]) != 0)
continue;
for(s = t->val; *s != 0; s++){
if(utf2idn(t->val, val, sizeof(val)) == nil)
continue;
for(s = val; *s != 0; s++){
for(l = 0; *s != 0 && *s != '.'; l++)
s++;
if(r+1+l > n)
@ -578,6 +581,8 @@ odomainlist(uchar *w, int n, Otab *o, Req *q)
w[r++] = l;
memmove(w+r, s-l, l);
r += l;
if(*s != '.')
break;
}
if(r >= n)
return -1;

View file

@ -1584,15 +1584,17 @@ hexopt(Req *rp, int t, char *str)
void
dnsnamesopt(Req *rp, int t, char *attr, Ndbtuple *nt)
{
char *s;
char val[Maxstr], *s;
uchar *d;
int n, l;
for(; nt != nil; nt = nt->entry){
if(strcmp(nt->attr, attr) != 0)
continue;
if(utf2idn(nt->val, val, sizeof(val)) == nil)
continue;
d = &rp->p[2];
for(s = nt->val; *s != 0; s++){
for(s = val; *s != 0; s++){
for(l = 0; *s != 0 && *s != '.'; l++)
s++;
if(l > 077)
@ -1602,6 +1604,8 @@ dnsnamesopt(Req *rp, int t, char *attr, Ndbtuple *nt)
return;
d[-l-1] = l;
memmove(d-l, s-l, l);
if(*s != '.')
break;
}
*d++ = 0;
n = d - &rp->p[2];
@ -1610,7 +1614,7 @@ dnsnamesopt(Req *rp, int t, char *attr, Ndbtuple *nt)
rp->p[0] = t;
rp->p[1] = n;
rp->p = d;
op = seprint(op, oe, "%s(%s)", optname[t], nt->val);
op = seprint(op, oe, "%s(%s)", optname[t], val);
Skip:;
}
}

View file

@ -305,7 +305,8 @@ lookupname(char *val, int len, Ndbtuple *t)
for(nt = t; nt != nil; nt = nt->entry)
if(strcmp(nt->attr, "dom") == 0){
strncpy(val, nt->val, len-1);
if(utf2idn(nt->val, val, len) == nil)
strncpy(val, nt->val, len-1);
val[len-1] = 0;
break;
}

View file

@ -47,6 +47,9 @@ static void doremove(void);
static void dounbind(void);
static void ndbconfig(void);
static int Ufmt(Fmt*);
#pragma varargck type "U" char*
void
usage(void)
{
@ -61,12 +64,14 @@ static void
init(void)
{
srand(truerand());
fmtinstall('H', encodefmt);
fmtinstall('E', eipfmt);
fmtinstall('I', eipfmt);
fmtinstall('M', eipfmt);
fmtinstall('V', eipfmt);
nsec(); /* make sure time file is open before forking */
fmtinstall('U', Ufmt);
nsec(); /* make sure time file is open before forking */
conf.cfd = -1;
conf.rfd = -1;
@ -193,7 +198,7 @@ parseargs(int argc, char **argv)
if(p == nil || *p == 0)
p = sysname();
if(p != nil)
strncpy(conf.hostname, p, sizeof conf.hostname-1);
utf2idn(p, conf.hostname, sizeof(conf.hostname));
}
/* defaults */
@ -636,11 +641,12 @@ putnames(char *p, char *e, char *attr, char *s)
char *x;
for(; *s != 0; s = x+1){
if((x = strchr(s, ' ')) == nil)
x = strchr(s, 0);
p = seprint(p, e, "%s=%.*s\n", attr, (int)(x - s), s);
if(*x == 0)
if((x = strchr(s, ' ')) != nil)
*x = 0;
p = seprint(p, e, "%s=%U\n", attr, s);
if(x == nil)
break;
*x = ' ';
}
return p;
}
@ -665,9 +671,9 @@ putndb(void)
*np = 0;
}
if(*conf.hostname)
p = seprint(p, e, "\tsys=%s\n", conf.hostname);
p = seprint(p, e, "\tsys=%U\n", conf.hostname);
if(*conf.domainname)
p = seprint(p, e, "\tdom=%s.%s\n",
p = seprint(p, e, "\tdom=%U.%U\n",
conf.hostname, conf.domainname);
if(*conf.dnsdomain)
p = putnames(p, e, "\tdnsdomain", conf.dnsdomain);
@ -967,6 +973,18 @@ gnames(char *d, int nd, uchar *s, int ns)
return d - (de - nd);
}
static int
Ufmt(Fmt *f)
{
char d[256], *s;
s = va_arg(f->args, char*);
if(idn2utf(s, d, sizeof(d)) != nil)
s = d;
fmtprint(f, "%s", s);
return 0;
}
static Ndbtuple*
uniquent(Ndbtuple *t)
{
@ -990,7 +1008,7 @@ void
ndb2conf(Ndb *db, uchar *myip)
{
int nattr;
char *attrs[10], val[64];
char *attrs[10], val[256];
uchar ip[IPaddrlen];
Ndbtuple *t, *nt;
@ -1021,7 +1039,9 @@ ndb2conf(Ndb *db, uchar *myip)
t = ndbipinfo(db, "ip", val, attrs, nattr);
for(nt = t; nt != nil; nt = nt->entry) {
if(strcmp(nt->attr, "dnsdomain") == 0) {
addnames(conf.dnsdomain, nt->val, sizeof(conf.dnsdomain));
if(utf2idn(nt->val, val, sizeof(val)) == nil)
continue;
addnames(conf.dnsdomain, val, sizeof(conf.dnsdomain));
continue;
}
if(strcmp(nt->attr, "ipmask") == 0) {

View file

@ -531,8 +531,4 @@ int convDNS2M(DNSmsg*, uchar*, int);
/* convM2DNS.c */
char* convM2DNS(uchar*, int, DNSmsg*, int*);
/* idn.c */
char* utf2idn(char *, char *, int);
char* idn2utf(char *, char *, int);
#pragma varargck argpos dnslog 1

View file

@ -17,16 +17,16 @@ TARG = \
inform\
DNSOBJ = dns.$O dnudpserver.$O dn.$O dnresolve.$O dblookup.$O dnserver.$O dnnotify.$O\
dnarea.$O convM2DNS.$O convDNS2M.$O idn.$O
dnarea.$O convM2DNS.$O convDNS2M.$O
DNSTCPOBJ = dnstcp.$O dn.$O dnresolve.$O dblookup.$O dnserver.$O\
dnarea.$O convM2DNS.$O convDNS2M.$O idn.$O
dnarea.$O convM2DNS.$O convDNS2M.$O
DNSDEBUGOBJ = dnsdebug.$O dn.$O dnresolve.$O dblookup.$O dnserver.$O\
dnarea.$O convM2DNS.$O convDNS2M.$O idn.$O
dnarea.$O convM2DNS.$O convDNS2M.$O
DNSGETIPOBJ = dnsgetip.$O dn.$O dnresolve.$O dblookup.$O dnserver.$O\
dnarea.$O convM2DNS.$O convDNS2M.$O idn.$O
dnarea.$O convM2DNS.$O convDNS2M.$O
HFILES = dns.h /$objtype/lib/libndb.a

View file

@ -25,10 +25,6 @@ Url* saneurl(Url *u);
int matchurl(Url *u, Url *s);
void freeurl(Url *u);
/* idn */
char* idn2utf(char *name, char *buf, int nbuf);
char* utf2idn(char *name, char *buf, int nbuf);
/* buq */
int buread(Buq *q, void *v, int l);
int buwrite(Buq *q, void *v, int l);

View file

@ -1,267 +0,0 @@
#include <u.h>
#include <libc.h>
#include <ctype.h>
#include <fcall.h>
#include <thread.h>
#include <9p.h>
#include "dat.h"
#include "fns.h"
enum {
base = 36,
tmin = 1,
tmax = 26,
skew = 38,
damp = 700,
initial_bias = 72,
initial_n = 0x80,
};
static uint maxint = ~0;
static uint
decode_digit(uint cp)
{
if((cp - '0') < 10)
return cp - ('0' - 26);
if((cp - 'A') < 26)
return cp - 'A';
if((cp - 'a') < 26)
return cp - 'a';
return base;
}
static char
encode_digit(uint d, int flag)
{
if(d < 26)
return d + (flag ? 'A' : 'a');
return d + ('0' - 26);
}
static uint
adapt(uint delta, uint numpoints, int firsttime)
{
uint k;
delta = firsttime ? delta / damp : delta >> 1;
delta += delta / numpoints;
for (k = 0; delta > ((base - tmin) * tmax) / 2; k += base)
delta /= base - tmin;
return k + (base - tmin + 1) * delta / (delta + skew);
}
static int
punyencode(uint input_length, Rune input[], uint max_out, char output[])
{
uint n, delta, h, b, out, bias, j, m, q, k, t;
n = initial_n;
delta = out = 0;
bias = initial_bias;
for (j = 0; j < input_length; ++j) {
if ((uint)input[j] < 0x80) {
if (max_out - out < 2)
return -1;
output[out++] = input[j];
}
}
h = b = out;
if (b > 0)
output[out++] = '-';
while (h < input_length) {
for (m = maxint, j = 0; j < input_length; ++j) {
if (input[j] >= n && input[j] < m)
m = input[j];
}
if (m - n > (maxint - delta) / (h + 1))
return -1;
delta += (m - n) * (h + 1);
n = m;
for (j = 0; j < input_length; ++j) {
if (input[j] < n) {
if (++delta == 0)
return -1;
}
if (input[j] == n) {
for (q = delta, k = base;; k += base) {
if (out >= max_out)
return -1;
if (k <= bias)
t = tmin;
else if (k >= bias + tmax)
t = tmax;
else
t = k - bias;
if (q < t)
break;
output[out++] = encode_digit(t + (q - t) % (base - t), 0);
q = (q - t) / (base - t);
}
output[out++] = encode_digit(q, isupperrune(input[j]));
bias = adapt(delta, h + 1, h == b);
delta = 0;
++h;
}
}
++delta, ++n;
}
return (int)out;
}
static int
punydecode(uint input_length, char input[], uint max_out, Rune output[])
{
uint n, out, i, bias, b, j, in, oldi, w, k, digit, t;
n = initial_n;
out = i = 0;
bias = initial_bias;
for (b = j = 0; j < input_length; ++j)
if (input[j] == '-')
b = j;
if (b > max_out)
return -1;
for (j = 0; j < b; ++j) {
if (input[j] & 0x80)
return -1;
output[out++] = input[j];
}
for (in = b > 0 ? b + 1 : 0; in < input_length; ++out) {
for (oldi = i, w = 1, k = base;; k += base) {
if (in >= input_length)
return -1;
digit = decode_digit(input[in++]);
if (digit >= base)
return -1;
if (digit > (maxint - i) / w)
return -1;
i += digit * w;
if (k <= bias)
t = tmin;
else if (k >= bias + tmax)
t = tmax;
else
t = k - bias;
if (digit < t)
break;
if (w > maxint / (base - t))
return -1;
w *= (base - t);
}
bias = adapt(i - oldi, out + 1, oldi == 0);
if (i / (out + 1) > maxint - n)
return -1;
n += i / (out + 1);
i %= (out + 1);
if (out >= max_out)
return -1;
memmove(output + i + 1, output + i, (out - i) * sizeof *output);
if(((uint)input[in-1] - 'A') < 26)
output[i++] = toupperrune(n);
else
output[i++] = tolowerrune(n);
}
return (int)out;
}
/*
* convert punycode encoded internationalized
* domain name to unicode string
*/
char*
idn2utf(char *name, char *buf, int nbuf)
{
char *dp, *de, *cp;
Rune rb[Domlen], r;
int nc, nr, n;
cp = name;
dp = buf;
de = dp+nbuf-1;
for(;;){
nc = nr = 0;
while(cp[nc] != 0){
n = chartorune(&r, cp+nc);
if(r == '.')
break;
rb[nr++] = r;
nc += n;
}
if(cistrncmp(cp, "xn--", 4) == 0)
if((nr = punydecode(nc-4, cp+4, nelem(rb), rb)) < 0)
return nil;
dp = seprint(dp, de, "%.*S", nr, rb);
if(dp >= de)
return nil;
if(cp[nc] == 0)
break;
*dp++ = '.';
cp += nc+1;
}
*dp = 0;
return buf;
}
/*
* convert unicode string to punycode
* encoded internationalized domain name
*/
char*
utf2idn(char *name, char *buf, int nbuf)
{
char *dp, *de, *cp;
Rune rb[Domlen], r;
int nc, nr, n;
dp = buf;
de = dp+nbuf-1;
cp = name;
for(;;){
nc = nr = 0;
while(cp[nc] != 0 && nr < nelem(rb)){
n = chartorune(&r, cp+nc);
if(r == '.')
break;
rb[nr++] = r;
nc += n;
}
if(nc == nr)
dp = seprint(dp, de, "%.*s", nc, cp);
else {
dp = seprint(dp, de, "xn--");
if((n = punyencode(nr, rb, de - dp, dp)) < 0)
return nil;
dp += n;
}
if(dp >= de)
return nil;
if(cp[nc] == 0)
break;
*dp++ = '.';
cp += nc+1;
}
*dp = 0;
return buf;
}

View file

@ -3,6 +3,6 @@ BIN=/$objtype/bin
TARG=webfs
HFILES=fns.h dat.h
OFILES=sub.$O url.$O buq.$O http.$O fs.$O idn.$O
OFILES=sub.$O url.$O buq.$O http.$O fs.$O
</sys/src/cmd/mkone

View file

@ -73,15 +73,12 @@ Efmt(Fmt *f)
int
Nfmt(Fmt *f)
{
char *d, *s;
char d[Domlen], *s;
s = va_arg(f->args, char*);
d = emalloc(Domlen);
if(utf2idn(s, d, Domlen) == nil)
d = s;
fmtprint(f, "%s", d);
if(d != s)
free(d);
if(utf2idn(s, d, sizeof(d)) != nil)
s = d;
fmtprint(f, "%s", s);
return 0;
}

View file

@ -1,7 +1,5 @@
#include <u.h>
#include <libc.h>
#include <ip.h>
#include "dns.h"
enum {
base = 36,
@ -11,6 +9,8 @@ enum {
damp = 700,
initial_bias = 72,
initial_n = 0x80,
Domlen = 256,
};
static uint maxint = ~0;

View file

@ -25,6 +25,7 @@ OFILES=\
getpid.$O\
getppid.$O\
getwd.$O\
idn.$O\
iounit.$O\
nsec.$O\
nulldir.$O\