First stab at parsing .priv key files with Ragel
This commit is contained in:
parent
92518b1c6a
commit
981f1853bc
60
kparse.rl
60
kparse.rl
|
@ -1 +1,61 @@
|
|||
package dns
|
||||
|
||||
// Parse private key files
|
||||
|
||||
import (
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
%%{
|
||||
machine k;
|
||||
write data;
|
||||
}%%
|
||||
|
||||
func Kparse(data string) (m map[string]string, err os.Error) {
|
||||
cs, p, pe, eof := 0, 0, len(data), len(data)
|
||||
mark := 0
|
||||
key := ""
|
||||
|
||||
%%{
|
||||
action mark { mark = p }
|
||||
action setKey { key = strings.ToLower(data[mark:p]) }
|
||||
action setValue { m[key] = data[mark:p] }
|
||||
|
||||
key = (
|
||||
('Private-key-format'i)
|
||||
| ('Algorithm'i)
|
||||
| ('Modules'i)
|
||||
| ('PublicExponent'i)
|
||||
| ('PrivateExponent'i)
|
||||
| ('Prime1'i)
|
||||
| ('Prime2'i)
|
||||
| ('Exponent1'i)
|
||||
| ('Exponent2'i)
|
||||
| ('Coefficient'i)
|
||||
| ('Created'i)
|
||||
| ('Publish'i)
|
||||
| ('Activate'i)
|
||||
);
|
||||
|
||||
value = any+;
|
||||
|
||||
line = key /: ?/ value;
|
||||
main := line+;
|
||||
|
||||
write init;
|
||||
write exec;
|
||||
}%%
|
||||
|
||||
if cs < z_first_final {
|
||||
// No clue what I'm doing what so ever
|
||||
if p == pe {
|
||||
//return nil, os.ErrorString("unexpected eof")
|
||||
return nil, nil
|
||||
} else {
|
||||
//return nil, os.ErrorString(fmt.Sprintf("error at position %d", p))
|
||||
return nil, nil
|
||||
}
|
||||
}
|
||||
return r ,nil
|
||||
}
|
||||
|
|
|
@ -139,8 +139,16 @@ func TestDotInName(t *testing.T) {
|
|||
|
||||
// New style (Ragel) parsing
|
||||
func TestParse(t *testing.T) {
|
||||
rr, _ := zparse("miek.nl. 3600 IN A 127.0.0.1")
|
||||
rr, _ := Zparse("miek.nl. 3600 IN A 127.0.0.1")
|
||||
fmt.Printf("Seen a:\n%v\n", rr)
|
||||
rr, _ = zparse("miek.nl. 3600 IN MX 10 elektron.atoom.net.")
|
||||
rr, _ = Zparse("miek.nl. 3600 IN MX 10 elektron.atoom.net.")
|
||||
fmt.Printf("Seen a:\n%v\n", rr)
|
||||
rr, _ = Zparse("nlnetlabs.nl. 3175 IN DNSKEY 256 3 8 AwEAAdR7XR95OaAN9Rz7TbtPalQ9guQk7zfxTHYNKhsiwTZA9z+F16nD0VeBlk7dNik3ETpT2GLAwr9sntG898JwurCDe353wHPvjZtMCdiTVp3cRCrjuCEvoFpmZNN82H0gaH/4v8mkv/QBDAkDSncYjz/FqHKAeYy3cMcjY6RyVweh");
|
||||
fmt.Printf("Seen a:\n%v\n", rr)
|
||||
rr, _ = Zparse("miek.nl. IN A 127.0.0.1")
|
||||
fmt.Printf("Seen a:\n%v\n", rr)
|
||||
rr, _ = Zparse("miek.nl. IN 3600 A 127.0.0.1")
|
||||
fmt.Printf("Seen a:\n%v\n", rr)
|
||||
rr, _ = Zparse("miek.nl. A 127.0.0.1")
|
||||
fmt.Printf("Seen a:\n%v\n", rr)
|
||||
}
|
||||
|
|
56
types.rl
56
types.rl
|
@ -7,51 +7,51 @@
|
|||
}
|
||||
action rdata_ns {
|
||||
r.(*RR_NS).Hdr = *hdr
|
||||
r.(*RR_NS).Ns = txt[0]
|
||||
r.(*RR_NS).Ns = tok.T[0]
|
||||
}
|
||||
action rdata_cname {
|
||||
r.(*RR_CNAME).Hdr = *hdr
|
||||
r.(*RR_CNAME).Cname = txt[0]
|
||||
r.(*RR_CNAME).Cname = tok.T[0]
|
||||
}
|
||||
action rdata_soa {
|
||||
r.(*RR_SOA).Hdr = *hdr
|
||||
r.(*RR_SOA).Ns = txt[0]
|
||||
r.(*RR_SOA).Mbox = txt[1]
|
||||
r.(*RR_SOA).Serial = uint32(num[0])
|
||||
r.(*RR_SOA).Refresh = uint32(num[1])
|
||||
r.(*RR_SOA).Retry = uint32(num[2])
|
||||
r.(*RR_SOA).Expire = uint32(num[3])
|
||||
r.(*RR_SOA).Minttl = uint32(num[4])
|
||||
r.(*RR_SOA).Ns = tok.T[0]
|
||||
r.(*RR_SOA).Mbox = tok.T[1]
|
||||
r.(*RR_SOA).Serial = uint32(tok.N[0])
|
||||
r.(*RR_SOA).Refresh = uint32(tok.N[1])
|
||||
r.(*RR_SOA).Retry = uint32(tok.N[2])
|
||||
r.(*RR_SOA).Expire = uint32(tok.N[3])
|
||||
r.(*RR_SOA).Minttl = uint32(tok.N[4])
|
||||
}
|
||||
action rdata_mx {
|
||||
r.(*RR_MX).Hdr = *hdr;
|
||||
r.(*RR_MX).Pref = uint16(num[0])
|
||||
r.(*RR_MX).Mx = txt[0]
|
||||
r.(*RR_MX).Pref = uint16(tok.N[0])
|
||||
r.(*RR_MX).Mx = tok.T[0]
|
||||
}
|
||||
action rdata_ds {
|
||||
r.(*RR_DS).Hdr = *hdr;
|
||||
r.(*RR_DS).KeyTag = uint16(num[0])
|
||||
r.(*RR_DS).Algorithm = uint8(num[1])
|
||||
r.(*RR_DS).DigestType = uint8(num[2])
|
||||
r.(*RR_DS).Digest = txt[0]
|
||||
r.(*RR_DS).KeyTag = uint16(tok.N[0])
|
||||
r.(*RR_DS).Algorithm = uint8(tok.N[1])
|
||||
r.(*RR_DS).DigestType = uint8(tok.N[2])
|
||||
r.(*RR_DS).Digest = tok.T[0]
|
||||
}
|
||||
action rdata_dnskey {
|
||||
r.(*RR_DNSKEY).Hdr = *hdr;
|
||||
r.(*RR_DNSKEY).Flags = uint16(num[0])
|
||||
r.(*RR_DNSKEY).Protocol = uint8(num[1])
|
||||
r.(*RR_DNSKEY).Algorithm = uint8(num[2])
|
||||
r.(*RR_DNSKEY).PublicKey = txt[0]
|
||||
r.(*RR_DNSKEY).Flags = uint16(tok.N[0])
|
||||
r.(*RR_DNSKEY).Protocol = uint8(tok.N[1])
|
||||
r.(*RR_DNSKEY).Algorithm = uint8(tok.N[2])
|
||||
r.(*RR_DNSKEY).PublicKey = tok.T[0]
|
||||
}
|
||||
action rdata_rrsig {
|
||||
r.(*RR_RRSIG).Hdr = *hdr;
|
||||
r.(*RR_RRSIG).TypeCovered = uint16(num[0])
|
||||
r.(*RR_RRSIG).Algorithm = uint8(num[1])
|
||||
r.(*RR_RRSIG).Labels = uint8(num[2])
|
||||
r.(*RR_RRSIG).OrigTtl = uint32(num[3])
|
||||
r.(*RR_RRSIG).Expiration = uint32(num[4])
|
||||
r.(*RR_RRSIG).Inception = uint32(num[5])
|
||||
r.(*RR_RRSIG).KeyTag = uint16(num[6])
|
||||
r.(*RR_RRSIG).SignerName = txt[0]
|
||||
r.(*RR_RRSIG).Signature = txt[1]
|
||||
r.(*RR_RRSIG).TypeCovered = uint16(tok.N[0])
|
||||
r.(*RR_RRSIG).Algorithm = uint8(tok.N[1])
|
||||
r.(*RR_RRSIG).Labels = uint8(tok.N[2])
|
||||
r.(*RR_RRSIG).OrigTtl = uint32(tok.N[3])
|
||||
r.(*RR_RRSIG).Expiration = uint32(tok.N[4])
|
||||
r.(*RR_RRSIG).Inception = uint32(tok.N[5])
|
||||
r.(*RR_RRSIG).KeyTag = uint16(tok.N[6])
|
||||
r.(*RR_RRSIG).SignerName = tok.T[0]
|
||||
r.(*RR_RRSIG).Signature = tok.T[1]
|
||||
}
|
||||
}%%
|
||||
|
|
93
zparse.rl
93
zparse.rl
|
@ -5,11 +5,55 @@ package dns
|
|||
|
||||
import (
|
||||
"os"
|
||||
"fmt"
|
||||
"net"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
const _RDATAMAX = 7
|
||||
|
||||
// Save up tokens, after we've seen the entire rdata
|
||||
// we can use this.
|
||||
type token struct {
|
||||
T []string // text
|
||||
N []int // number
|
||||
ti int // text counter
|
||||
ni int // number counter
|
||||
}
|
||||
|
||||
func newToken() *token {
|
||||
to := new(token)
|
||||
to.T = make([]string, _RDATAMAX)
|
||||
to.N = make([]int, _RDATAMAX)
|
||||
to.ni, to.ti = 0, 0
|
||||
return to
|
||||
}
|
||||
|
||||
// Only push functions are provided. Reading is done, by directly
|
||||
// accessing the members (T and N). See types.rl.
|
||||
func (to *token) pushInt(s string) {
|
||||
i, err := strconv.Atoi(s)
|
||||
if err != nil {
|
||||
panic("Failure to parse to int: " + s)
|
||||
}
|
||||
to.N[to.ni] = i
|
||||
to.ni++
|
||||
if to.ni > _RDATAMAX {
|
||||
panic("Too much rdata (int)")
|
||||
}
|
||||
}
|
||||
|
||||
func (to *token) pushString(s string) {
|
||||
to.T[to.ti] = s
|
||||
to.ti++
|
||||
if to.ti > _RDATAMAX {
|
||||
panic("Too much rdata (string)")
|
||||
}
|
||||
}
|
||||
|
||||
func (to *token) reset() {
|
||||
to.ni, to.ti = 0, 0
|
||||
}
|
||||
|
||||
%%{
|
||||
machine z;
|
||||
write data;
|
||||
|
@ -17,22 +61,19 @@ import (
|
|||
|
||||
func Zparse(data string) (r RR, err os.Error) {
|
||||
cs, p, pe, eof := 0, 0, len(data), len(data)
|
||||
j := 0; j = j // Needed for compile.
|
||||
k := 0; k = k // "
|
||||
mark := 0
|
||||
hdr := new(RR_Header)
|
||||
txt := make([]string, 7)
|
||||
num := make([]int, 7)
|
||||
tok := newToken()
|
||||
|
||||
%%{
|
||||
action mark { mark = p }
|
||||
action qname { hdr.Name = data[mark:p] }
|
||||
action number { n, _ := strconv.Atoi(data[mark:p]); num[j] = n; j++ }
|
||||
action text { txt[k] = data[mark:p]; k++ }
|
||||
action textblank { txt[k] = data[mark:p]; k++ }
|
||||
action qclass { hdr.Class = Str_class[data[mark:p]] }
|
||||
action defTtl { /* fmt.Printf("defttl {%s}\n", data[mark:p]) */ }
|
||||
action defTtl { /* ... */ }
|
||||
action setTtl { ttl, _ := strconv.Atoi(data[mark:p]); hdr.Ttl = uint32(ttl) }
|
||||
action number { tok.pushInt(data[mark:p]) }
|
||||
action text { tok.pushString(data[mark:p]) }
|
||||
action textblank { tok.pushString(data[mark:p]) }
|
||||
|
||||
action qtype {
|
||||
i := Str_rr[data[mark:p]]
|
||||
|
@ -46,15 +87,17 @@ func Zparse(data string) (r RR, err os.Error) {
|
|||
|
||||
qclass = ('IN'i|'CS'i|'CH'i|'HS'i|'ANY'i|'NONE'i) %qclass;
|
||||
ttl = digit+ >mark;
|
||||
b = [ \t]+ %mark;
|
||||
bl = [ \t]+ %mark;
|
||||
qname = [a-zA-Z0-9.\\]+ %qname;
|
||||
# If I use this in the definitions at the end, things break...
|
||||
tb = [a-zA-Z0-9.\\ ]+ $1 %0 %textblank;
|
||||
t = [a-zA-Z0-9.\\]+ $1 %0 %text;
|
||||
# t = [a-zA-Z0-9.\\]+ $1 %0 %text;
|
||||
t = [a-zA-Z0-9.\\/+=]+ $1 %0 %text;
|
||||
n = [0-9]+ $1 %0 %number;
|
||||
|
||||
lhs = qname? b %defTtl (
|
||||
(ttl %setTtl b (qclass b)?)
|
||||
| (qclass b (ttl %setTtl b)?)
|
||||
lhs = qname? bl %defTtl (
|
||||
(ttl %setTtl bl (qclass bl)?)
|
||||
| (qclass bl (ttl %setTtl bl)?)
|
||||
)?;
|
||||
|
||||
# RDATA definitions
|
||||
|
@ -62,14 +105,14 @@ func Zparse(data string) (r RR, err os.Error) {
|
|||
|
||||
# RR definitions
|
||||
rhs = (
|
||||
('A'i %qtype b t) %rdata_a
|
||||
| ('NS'i %qtype b t) %rdata_ns
|
||||
| ('CNAME'i %qtype b t) %rdata_cname
|
||||
| ('SOA'i %qtype b tb t b n b n b n b n b n) %rdata_soa
|
||||
| ('MX'i %qtype b n b t) %rdata_mx
|
||||
| ('DS'i %qtype b n b n b n b tb) %rdata_ds
|
||||
| ('DNSKEY'i %qtype b n b n b n b tb) %rdata_dnskey
|
||||
| ('RRSIG'i %qtype b n b n b n b n b n b n b n b t b tb) %rdata_rrsig
|
||||
('A'i %qtype bl t) %rdata_a
|
||||
| ('NS'i %qtype bl t) %rdata_ns
|
||||
| ('CNAME'i %qtype bl t) %rdata_cname
|
||||
| ('SOA'i %qtype bl t bl t bl n bl n bl n bl n bl n) %rdata_soa
|
||||
| ('MX'i %qtype bl n bl t) %rdata_mx
|
||||
| ('DS'i %qtype bl n bl n bl n bl t) %rdata_ds
|
||||
| ('DNSKEY'i %qtype bl n bl n bl n bl t) %rdata_dnskey
|
||||
| ('RRSIG'i %qtype bl n bl n bl n bl n bl n bl n bl n bl t bl t) %rdata_rrsig
|
||||
);
|
||||
|
||||
rr = lhs rhs;
|
||||
|
@ -82,9 +125,11 @@ func Zparse(data string) (r RR, err os.Error) {
|
|||
if cs < z_first_final {
|
||||
// No clue what I'm doing what so ever
|
||||
if p == pe {
|
||||
return nil, os.ErrorString("unexpected eof")
|
||||
//return nil, os.ErrorString("unexpected eof")
|
||||
return nil, nil
|
||||
} else {
|
||||
return nil, os.ErrorString(fmt.Sprintf("error at position %d", p))
|
||||
//return nil, os.ErrorString(fmt.Sprintf("error at position %d", p))
|
||||
return nil, nil
|
||||
}
|
||||
}
|
||||
return r ,nil
|
||||
|
|
Loading…
Reference in New Issue