scan.go 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338
  1. package dns
  2. import (
  3. "bufio"
  4. "fmt"
  5. "io"
  6. "os"
  7. "path/filepath"
  8. "strconv"
  9. "strings"
  10. )
  11. const maxTok = 2048 // Largest token we can return.
  12. // The maximum depth of $INCLUDE directives supported by the
  13. // ZoneParser API.
  14. const maxIncludeDepth = 7
  15. // Tokinize a RFC 1035 zone file. The tokenizer will normalize it:
  16. // * Add ownernames if they are left blank;
  17. // * Suppress sequences of spaces;
  18. // * Make each RR fit on one line (_NEWLINE is send as last)
  19. // * Handle comments: ;
  20. // * Handle braces - anywhere.
  21. const (
  22. // Zonefile
  23. zEOF = iota
  24. zString
  25. zBlank
  26. zQuote
  27. zNewline
  28. zRrtpe
  29. zOwner
  30. zClass
  31. zDirOrigin // $ORIGIN
  32. zDirTTL // $TTL
  33. zDirInclude // $INCLUDE
  34. zDirGenerate // $GENERATE
  35. // Privatekey file
  36. zValue
  37. zKey
  38. zExpectOwnerDir // Ownername
  39. zExpectOwnerBl // Whitespace after the ownername
  40. zExpectAny // Expect rrtype, ttl or class
  41. zExpectAnyNoClass // Expect rrtype or ttl
  42. zExpectAnyNoClassBl // The whitespace after _EXPECT_ANY_NOCLASS
  43. zExpectAnyNoTTL // Expect rrtype or class
  44. zExpectAnyNoTTLBl // Whitespace after _EXPECT_ANY_NOTTL
  45. zExpectRrtype // Expect rrtype
  46. zExpectRrtypeBl // Whitespace BEFORE rrtype
  47. zExpectRdata // The first element of the rdata
  48. zExpectDirTTLBl // Space after directive $TTL
  49. zExpectDirTTL // Directive $TTL
  50. zExpectDirOriginBl // Space after directive $ORIGIN
  51. zExpectDirOrigin // Directive $ORIGIN
  52. zExpectDirIncludeBl // Space after directive $INCLUDE
  53. zExpectDirInclude // Directive $INCLUDE
  54. zExpectDirGenerate // Directive $GENERATE
  55. zExpectDirGenerateBl // Space after directive $GENERATE
  56. )
  57. // ParseError is a parsing error. It contains the parse error and the location in the io.Reader
  58. // where the error occurred.
  59. type ParseError struct {
  60. file string
  61. err string
  62. lex lex
  63. }
  64. func (e *ParseError) Error() (s string) {
  65. if e.file != "" {
  66. s = e.file + ": "
  67. }
  68. s += "dns: " + e.err + ": " + strconv.QuoteToASCII(e.lex.token) + " at line: " +
  69. strconv.Itoa(e.lex.line) + ":" + strconv.Itoa(e.lex.column)
  70. return
  71. }
  72. type lex struct {
  73. token string // text of the token
  74. err bool // when true, token text has lexer error
  75. value uint8 // value: zString, _BLANK, etc.
  76. torc uint16 // type or class as parsed in the lexer, we only need to look this up in the grammar
  77. line int // line in the file
  78. column int // column in the file
  79. }
  80. // Token holds the token that are returned when a zone file is parsed.
  81. type Token struct {
  82. // The scanned resource record when error is not nil.
  83. RR
  84. // When an error occurred, this has the error specifics.
  85. Error *ParseError
  86. // A potential comment positioned after the RR and on the same line.
  87. Comment string
  88. }
  89. // ttlState describes the state necessary to fill in an omitted RR TTL
  90. type ttlState struct {
  91. ttl uint32 // ttl is the current default TTL
  92. isByDirective bool // isByDirective indicates whether ttl was set by a $TTL directive
  93. }
  94. // NewRR reads the RR contained in the string s. Only the first RR is
  95. // returned. If s contains no records, NewRR will return nil with no
  96. // error.
  97. //
  98. // The class defaults to IN and TTL defaults to 3600. The full zone
  99. // file syntax like $TTL, $ORIGIN, etc. is supported.
  100. //
  101. // All fields of the returned RR are set, except RR.Header().Rdlength
  102. // which is set to 0.
  103. func NewRR(s string) (RR, error) {
  104. if len(s) > 0 && s[len(s)-1] != '\n' { // We need a closing newline
  105. return ReadRR(strings.NewReader(s+"\n"), "")
  106. }
  107. return ReadRR(strings.NewReader(s), "")
  108. }
  109. // ReadRR reads the RR contained in r.
  110. //
  111. // The string file is used in error reporting and to resolve relative
  112. // $INCLUDE directives.
  113. //
  114. // See NewRR for more documentation.
  115. func ReadRR(r io.Reader, file string) (RR, error) {
  116. zp := NewZoneParser(r, ".", file)
  117. zp.SetDefaultTTL(defaultTtl)
  118. zp.SetIncludeAllowed(true)
  119. rr, _ := zp.Next()
  120. return rr, zp.Err()
  121. }
  122. // ParseZone reads a RFC 1035 style zonefile from r. It returns
  123. // *Tokens on the returned channel, each consisting of either a
  124. // parsed RR and optional comment or a nil RR and an error. The
  125. // channel is closed by ParseZone when the end of r is reached.
  126. //
  127. // The string file is used in error reporting and to resolve relative
  128. // $INCLUDE directives. The string origin is used as the initial
  129. // origin, as if the file would start with an $ORIGIN directive.
  130. //
  131. // The directives $INCLUDE, $ORIGIN, $TTL and $GENERATE are all
  132. // supported.
  133. //
  134. // Basic usage pattern when reading from a string (z) containing the
  135. // zone data:
  136. //
  137. // for x := range dns.ParseZone(strings.NewReader(z), "", "") {
  138. // if x.Error != nil {
  139. // // log.Println(x.Error)
  140. // } else {
  141. // // Do something with x.RR
  142. // }
  143. // }
  144. //
  145. // Comments specified after an RR (and on the same line!) are
  146. // returned too:
  147. //
  148. // foo. IN A 10.0.0.1 ; this is a comment
  149. //
  150. // The text "; this is comment" is returned in Token.Comment.
  151. // Comments inside the RR are returned concatenated along with the
  152. // RR. Comments on a line by themselves are discarded.
  153. //
  154. // To prevent memory leaks it is important to always fully drain the
  155. // returned channel. If an error occurs, it will always be the last
  156. // Token sent on the channel.
  157. //
  158. // Deprecated: New users should prefer the ZoneParser API.
  159. func ParseZone(r io.Reader, origin, file string) chan *Token {
  160. t := make(chan *Token, 10000)
  161. go parseZone(r, origin, file, t)
  162. return t
  163. }
  164. func parseZone(r io.Reader, origin, file string, t chan *Token) {
  165. defer close(t)
  166. zp := NewZoneParser(r, origin, file)
  167. zp.SetIncludeAllowed(true)
  168. for rr, ok := zp.Next(); ok; rr, ok = zp.Next() {
  169. t <- &Token{RR: rr, Comment: zp.Comment()}
  170. }
  171. if err := zp.Err(); err != nil {
  172. pe, ok := err.(*ParseError)
  173. if !ok {
  174. pe = &ParseError{file: file, err: err.Error()}
  175. }
  176. t <- &Token{Error: pe}
  177. }
  178. }
  179. // ZoneParser is a parser for an RFC 1035 style zonefile.
  180. //
  181. // Each parsed RR in the zone is returned sequentially from Next. An
  182. // optional comment can be retrieved with Comment.
  183. //
  184. // The directives $INCLUDE, $ORIGIN, $TTL and $GENERATE are all
  185. // supported. Although $INCLUDE is disabled by default.
  186. //
  187. // Basic usage pattern when reading from a string (z) containing the
  188. // zone data:
  189. //
  190. // zp := NewZoneParser(strings.NewReader(z), "", "")
  191. //
  192. // for rr, ok := zp.Next(); ok; rr, ok = zp.Next() {
  193. // // Do something with rr
  194. // }
  195. //
  196. // if err := zp.Err(); err != nil {
  197. // // log.Println(err)
  198. // }
  199. //
  200. // Comments specified after an RR (and on the same line!) are
  201. // returned too:
  202. //
  203. // foo. IN A 10.0.0.1 ; this is a comment
  204. //
  205. // The text "; this is comment" is returned from Comment. Comments inside
  206. // the RR are returned concatenated along with the RR. Comments on a line
  207. // by themselves are discarded.
  208. type ZoneParser struct {
  209. c *zlexer
  210. parseErr *ParseError
  211. origin string
  212. file string
  213. defttl *ttlState
  214. h RR_Header
  215. // sub is used to parse $INCLUDE files and $GENERATE directives.
  216. // Next, by calling subNext, forwards the resulting RRs from this
  217. // sub parser to the calling code.
  218. sub *ZoneParser
  219. osFile *os.File
  220. includeDepth uint8
  221. includeAllowed bool
  222. }
  223. // NewZoneParser returns an RFC 1035 style zonefile parser that reads
  224. // from r.
  225. //
  226. // The string file is used in error reporting and to resolve relative
  227. // $INCLUDE directives. The string origin is used as the initial
  228. // origin, as if the file would start with an $ORIGIN directive.
  229. func NewZoneParser(r io.Reader, origin, file string) *ZoneParser {
  230. var pe *ParseError
  231. if origin != "" {
  232. origin = Fqdn(origin)
  233. if _, ok := IsDomainName(origin); !ok {
  234. pe = &ParseError{file, "bad initial origin name", lex{}}
  235. }
  236. }
  237. return &ZoneParser{
  238. c: newZLexer(r),
  239. parseErr: pe,
  240. origin: origin,
  241. file: file,
  242. }
  243. }
  244. // SetDefaultTTL sets the parsers default TTL to ttl.
  245. func (zp *ZoneParser) SetDefaultTTL(ttl uint32) {
  246. zp.defttl = &ttlState{ttl, false}
  247. }
  248. // SetIncludeAllowed controls whether $INCLUDE directives are
  249. // allowed. $INCLUDE directives are not supported by default.
  250. //
  251. // The $INCLUDE directive will open and read from a user controlled
  252. // file on the system. Even if the file is not a valid zonefile, the
  253. // contents of the file may be revealed in error messages, such as:
  254. //
  255. // /etc/passwd: dns: not a TTL: "root:x:0:0:root:/root:/bin/bash" at line: 1:31
  256. // /etc/shadow: dns: not a TTL: "root:$6$<redacted>::0:99999:7:::" at line: 1:125
  257. func (zp *ZoneParser) SetIncludeAllowed(v bool) {
  258. zp.includeAllowed = v
  259. }
  260. // Err returns the first non-EOF error that was encountered by the
  261. // ZoneParser.
  262. func (zp *ZoneParser) Err() error {
  263. if zp.parseErr != nil {
  264. return zp.parseErr
  265. }
  266. if zp.sub != nil {
  267. if err := zp.sub.Err(); err != nil {
  268. return err
  269. }
  270. }
  271. return zp.c.Err()
  272. }
  273. func (zp *ZoneParser) setParseError(err string, l lex) (RR, bool) {
  274. zp.parseErr = &ParseError{zp.file, err, l}
  275. return nil, false
  276. }
  277. // Comment returns an optional text comment that occurred alongside
  278. // the RR.
  279. func (zp *ZoneParser) Comment() string {
  280. if zp.parseErr != nil {
  281. return ""
  282. }
  283. if zp.sub != nil {
  284. return zp.sub.Comment()
  285. }
  286. return zp.c.Comment()
  287. }
  288. func (zp *ZoneParser) subNext() (RR, bool) {
  289. if rr, ok := zp.sub.Next(); ok {
  290. return rr, true
  291. }
  292. if zp.sub.osFile != nil {
  293. zp.sub.osFile.Close()
  294. zp.sub.osFile = nil
  295. }
  296. if zp.sub.Err() != nil {
  297. // We have errors to surface.
  298. return nil, false
  299. }
  300. zp.sub = nil
  301. return zp.Next()
  302. }
  303. // Next advances the parser to the next RR in the zonefile and
  304. // returns the (RR, true). It will return (nil, false) when the
  305. // parsing stops, either by reaching the end of the input or an
  306. // error. After Next returns (nil, false), the Err method will return
  307. // any error that occurred during parsing.
  308. func (zp *ZoneParser) Next() (RR, bool) {
  309. if zp.parseErr != nil {
  310. return nil, false
  311. }
  312. if zp.sub != nil {
  313. return zp.subNext()
  314. }
  315. // 6 possible beginnings of a line (_ is a space):
  316. //
  317. // 0. zRRTYPE -> all omitted until the rrtype
  318. // 1. zOwner _ zRrtype -> class/ttl omitted
  319. // 2. zOwner _ zString _ zRrtype -> class omitted
  320. // 3. zOwner _ zString _ zClass _ zRrtype -> ttl/class
  321. // 4. zOwner _ zClass _ zRrtype -> ttl omitted
  322. // 5. zOwner _ zClass _ zString _ zRrtype -> class/ttl (reversed)
  323. //
  324. // After detecting these, we know the zRrtype so we can jump to functions
  325. // handling the rdata for each of these types.
  326. st := zExpectOwnerDir // initial state
  327. h := &zp.h
  328. for l, ok := zp.c.Next(); ok; l, ok = zp.c.Next() {
  329. // zlexer spotted an error already
  330. if l.err {
  331. return zp.setParseError(l.token, l)
  332. }
  333. switch st {
  334. case zExpectOwnerDir:
  335. // We can also expect a directive, like $TTL or $ORIGIN
  336. if zp.defttl != nil {
  337. h.Ttl = zp.defttl.ttl
  338. }
  339. h.Class = ClassINET
  340. switch l.value {
  341. case zNewline:
  342. st = zExpectOwnerDir
  343. case zOwner:
  344. name, ok := toAbsoluteName(l.token, zp.origin)
  345. if !ok {
  346. return zp.setParseError("bad owner name", l)
  347. }
  348. h.Name = name
  349. st = zExpectOwnerBl
  350. case zDirTTL:
  351. st = zExpectDirTTLBl
  352. case zDirOrigin:
  353. st = zExpectDirOriginBl
  354. case zDirInclude:
  355. st = zExpectDirIncludeBl
  356. case zDirGenerate:
  357. st = zExpectDirGenerateBl
  358. case zRrtpe:
  359. h.Rrtype = l.torc
  360. st = zExpectRdata
  361. case zClass:
  362. h.Class = l.torc
  363. st = zExpectAnyNoClassBl
  364. case zBlank:
  365. // Discard, can happen when there is nothing on the
  366. // line except the RR type
  367. case zString:
  368. ttl, ok := stringToTTL(l.token)
  369. if !ok {
  370. return zp.setParseError("not a TTL", l)
  371. }
  372. h.Ttl = ttl
  373. if zp.defttl == nil || !zp.defttl.isByDirective {
  374. zp.defttl = &ttlState{ttl, false}
  375. }
  376. st = zExpectAnyNoTTLBl
  377. default:
  378. return zp.setParseError("syntax error at beginning", l)
  379. }
  380. case zExpectDirIncludeBl:
  381. if l.value != zBlank {
  382. return zp.setParseError("no blank after $INCLUDE-directive", l)
  383. }
  384. st = zExpectDirInclude
  385. case zExpectDirInclude:
  386. if l.value != zString {
  387. return zp.setParseError("expecting $INCLUDE value, not this...", l)
  388. }
  389. neworigin := zp.origin // There may be optionally a new origin set after the filename, if not use current one
  390. switch l, _ := zp.c.Next(); l.value {
  391. case zBlank:
  392. l, _ := zp.c.Next()
  393. if l.value == zString {
  394. name, ok := toAbsoluteName(l.token, zp.origin)
  395. if !ok {
  396. return zp.setParseError("bad origin name", l)
  397. }
  398. neworigin = name
  399. }
  400. case zNewline, zEOF:
  401. // Ok
  402. default:
  403. return zp.setParseError("garbage after $INCLUDE", l)
  404. }
  405. if !zp.includeAllowed {
  406. return zp.setParseError("$INCLUDE directive not allowed", l)
  407. }
  408. if zp.includeDepth >= maxIncludeDepth {
  409. return zp.setParseError("too deeply nested $INCLUDE", l)
  410. }
  411. // Start with the new file
  412. includePath := l.token
  413. if !filepath.IsAbs(includePath) {
  414. includePath = filepath.Join(filepath.Dir(zp.file), includePath)
  415. }
  416. r1, e1 := os.Open(includePath)
  417. if e1 != nil {
  418. var as string
  419. if !filepath.IsAbs(l.token) {
  420. as = fmt.Sprintf(" as `%s'", includePath)
  421. }
  422. msg := fmt.Sprintf("failed to open `%s'%s: %v", l.token, as, e1)
  423. return zp.setParseError(msg, l)
  424. }
  425. zp.sub = NewZoneParser(r1, neworigin, includePath)
  426. zp.sub.defttl, zp.sub.includeDepth, zp.sub.osFile = zp.defttl, zp.includeDepth+1, r1
  427. zp.sub.SetIncludeAllowed(true)
  428. return zp.subNext()
  429. case zExpectDirTTLBl:
  430. if l.value != zBlank {
  431. return zp.setParseError("no blank after $TTL-directive", l)
  432. }
  433. st = zExpectDirTTL
  434. case zExpectDirTTL:
  435. if l.value != zString {
  436. return zp.setParseError("expecting $TTL value, not this...", l)
  437. }
  438. if e := slurpRemainder(zp.c, zp.file); e != nil {
  439. zp.parseErr = e
  440. return nil, false
  441. }
  442. ttl, ok := stringToTTL(l.token)
  443. if !ok {
  444. return zp.setParseError("expecting $TTL value, not this...", l)
  445. }
  446. zp.defttl = &ttlState{ttl, true}
  447. st = zExpectOwnerDir
  448. case zExpectDirOriginBl:
  449. if l.value != zBlank {
  450. return zp.setParseError("no blank after $ORIGIN-directive", l)
  451. }
  452. st = zExpectDirOrigin
  453. case zExpectDirOrigin:
  454. if l.value != zString {
  455. return zp.setParseError("expecting $ORIGIN value, not this...", l)
  456. }
  457. if e := slurpRemainder(zp.c, zp.file); e != nil {
  458. zp.parseErr = e
  459. return nil, false
  460. }
  461. name, ok := toAbsoluteName(l.token, zp.origin)
  462. if !ok {
  463. return zp.setParseError("bad origin name", l)
  464. }
  465. zp.origin = name
  466. st = zExpectOwnerDir
  467. case zExpectDirGenerateBl:
  468. if l.value != zBlank {
  469. return zp.setParseError("no blank after $GENERATE-directive", l)
  470. }
  471. st = zExpectDirGenerate
  472. case zExpectDirGenerate:
  473. if l.value != zString {
  474. return zp.setParseError("expecting $GENERATE value, not this...", l)
  475. }
  476. return zp.generate(l)
  477. case zExpectOwnerBl:
  478. if l.value != zBlank {
  479. return zp.setParseError("no blank after owner", l)
  480. }
  481. st = zExpectAny
  482. case zExpectAny:
  483. switch l.value {
  484. case zRrtpe:
  485. if zp.defttl == nil {
  486. return zp.setParseError("missing TTL with no previous value", l)
  487. }
  488. h.Rrtype = l.torc
  489. st = zExpectRdata
  490. case zClass:
  491. h.Class = l.torc
  492. st = zExpectAnyNoClassBl
  493. case zString:
  494. ttl, ok := stringToTTL(l.token)
  495. if !ok {
  496. return zp.setParseError("not a TTL", l)
  497. }
  498. h.Ttl = ttl
  499. if zp.defttl == nil || !zp.defttl.isByDirective {
  500. zp.defttl = &ttlState{ttl, false}
  501. }
  502. st = zExpectAnyNoTTLBl
  503. default:
  504. return zp.setParseError("expecting RR type, TTL or class, not this...", l)
  505. }
  506. case zExpectAnyNoClassBl:
  507. if l.value != zBlank {
  508. return zp.setParseError("no blank before class", l)
  509. }
  510. st = zExpectAnyNoClass
  511. case zExpectAnyNoTTLBl:
  512. if l.value != zBlank {
  513. return zp.setParseError("no blank before TTL", l)
  514. }
  515. st = zExpectAnyNoTTL
  516. case zExpectAnyNoTTL:
  517. switch l.value {
  518. case zClass:
  519. h.Class = l.torc
  520. st = zExpectRrtypeBl
  521. case zRrtpe:
  522. h.Rrtype = l.torc
  523. st = zExpectRdata
  524. default:
  525. return zp.setParseError("expecting RR type or class, not this...", l)
  526. }
  527. case zExpectAnyNoClass:
  528. switch l.value {
  529. case zString:
  530. ttl, ok := stringToTTL(l.token)
  531. if !ok {
  532. return zp.setParseError("not a TTL", l)
  533. }
  534. h.Ttl = ttl
  535. if zp.defttl == nil || !zp.defttl.isByDirective {
  536. zp.defttl = &ttlState{ttl, false}
  537. }
  538. st = zExpectRrtypeBl
  539. case zRrtpe:
  540. h.Rrtype = l.torc
  541. st = zExpectRdata
  542. default:
  543. return zp.setParseError("expecting RR type or TTL, not this...", l)
  544. }
  545. case zExpectRrtypeBl:
  546. if l.value != zBlank {
  547. return zp.setParseError("no blank before RR type", l)
  548. }
  549. st = zExpectRrtype
  550. case zExpectRrtype:
  551. if l.value != zRrtpe {
  552. return zp.setParseError("unknown RR type", l)
  553. }
  554. h.Rrtype = l.torc
  555. st = zExpectRdata
  556. case zExpectRdata:
  557. r, e := setRR(*h, zp.c, zp.origin, zp.file)
  558. if e != nil {
  559. // If e.lex is nil than we have encounter a unknown RR type
  560. // in that case we substitute our current lex token
  561. if e.lex.token == "" && e.lex.value == 0 {
  562. e.lex = l // Uh, dirty
  563. }
  564. zp.parseErr = e
  565. return nil, false
  566. }
  567. return r, true
  568. }
  569. }
  570. // If we get here, we and the h.Rrtype is still zero, we haven't parsed anything, this
  571. // is not an error, because an empty zone file is still a zone file.
  572. return nil, false
  573. }
  574. type zlexer struct {
  575. br io.ByteReader
  576. readErr error
  577. line int
  578. column int
  579. comBuf string
  580. comment string
  581. l lex
  582. brace int
  583. quote bool
  584. space bool
  585. commt bool
  586. rrtype bool
  587. owner bool
  588. nextL bool
  589. eol bool // end-of-line
  590. }
  591. func newZLexer(r io.Reader) *zlexer {
  592. br, ok := r.(io.ByteReader)
  593. if !ok {
  594. br = bufio.NewReaderSize(r, 1024)
  595. }
  596. return &zlexer{
  597. br: br,
  598. line: 1,
  599. owner: true,
  600. }
  601. }
  602. func (zl *zlexer) Err() error {
  603. if zl.readErr == io.EOF {
  604. return nil
  605. }
  606. return zl.readErr
  607. }
  608. // readByte returns the next byte from the input
  609. func (zl *zlexer) readByte() (byte, bool) {
  610. if zl.readErr != nil {
  611. return 0, false
  612. }
  613. c, err := zl.br.ReadByte()
  614. if err != nil {
  615. zl.readErr = err
  616. return 0, false
  617. }
  618. // delay the newline handling until the next token is delivered,
  619. // fixes off-by-one errors when reporting a parse error.
  620. if zl.eol {
  621. zl.line++
  622. zl.column = 0
  623. zl.eol = false
  624. }
  625. if c == '\n' {
  626. zl.eol = true
  627. } else {
  628. zl.column++
  629. }
  630. return c, true
  631. }
  632. func (zl *zlexer) Next() (lex, bool) {
  633. l := &zl.l
  634. if zl.nextL {
  635. zl.nextL = false
  636. return *l, true
  637. }
  638. if l.err {
  639. // Parsing errors should be sticky.
  640. return lex{value: zEOF}, false
  641. }
  642. var (
  643. str [maxTok]byte // Hold string text
  644. com [maxTok]byte // Hold comment text
  645. stri int // Offset in str (0 means empty)
  646. comi int // Offset in com (0 means empty)
  647. escape bool
  648. )
  649. if zl.comBuf != "" {
  650. comi = copy(com[:], zl.comBuf)
  651. zl.comBuf = ""
  652. }
  653. zl.comment = ""
  654. for x, ok := zl.readByte(); ok; x, ok = zl.readByte() {
  655. l.line, l.column = zl.line, zl.column
  656. if stri >= len(str) {
  657. l.token = "token length insufficient for parsing"
  658. l.err = true
  659. return *l, true
  660. }
  661. if comi >= len(com) {
  662. l.token = "comment length insufficient for parsing"
  663. l.err = true
  664. return *l, true
  665. }
  666. switch x {
  667. case ' ', '\t':
  668. if escape || zl.quote {
  669. // Inside quotes or escaped this is legal.
  670. str[stri] = x
  671. stri++
  672. escape = false
  673. break
  674. }
  675. if zl.commt {
  676. com[comi] = x
  677. comi++
  678. break
  679. }
  680. var retL lex
  681. if stri == 0 {
  682. // Space directly in the beginning, handled in the grammar
  683. } else if zl.owner {
  684. // If we have a string and its the first, make it an owner
  685. l.value = zOwner
  686. l.token = string(str[:stri])
  687. // escape $... start with a \ not a $, so this will work
  688. switch strings.ToUpper(l.token) {
  689. case "$TTL":
  690. l.value = zDirTTL
  691. case "$ORIGIN":
  692. l.value = zDirOrigin
  693. case "$INCLUDE":
  694. l.value = zDirInclude
  695. case "$GENERATE":
  696. l.value = zDirGenerate
  697. }
  698. retL = *l
  699. } else {
  700. l.value = zString
  701. l.token = string(str[:stri])
  702. if !zl.rrtype {
  703. tokenUpper := strings.ToUpper(l.token)
  704. if t, ok := StringToType[tokenUpper]; ok {
  705. l.value = zRrtpe
  706. l.torc = t
  707. zl.rrtype = true
  708. } else if strings.HasPrefix(tokenUpper, "TYPE") {
  709. t, ok := typeToInt(l.token)
  710. if !ok {
  711. l.token = "unknown RR type"
  712. l.err = true
  713. return *l, true
  714. }
  715. l.value = zRrtpe
  716. l.torc = t
  717. zl.rrtype = true
  718. }
  719. if t, ok := StringToClass[tokenUpper]; ok {
  720. l.value = zClass
  721. l.torc = t
  722. } else if strings.HasPrefix(tokenUpper, "CLASS") {
  723. t, ok := classToInt(l.token)
  724. if !ok {
  725. l.token = "unknown class"
  726. l.err = true
  727. return *l, true
  728. }
  729. l.value = zClass
  730. l.torc = t
  731. }
  732. }
  733. retL = *l
  734. }
  735. zl.owner = false
  736. if !zl.space {
  737. zl.space = true
  738. l.value = zBlank
  739. l.token = " "
  740. if retL == (lex{}) {
  741. return *l, true
  742. }
  743. zl.nextL = true
  744. }
  745. if retL != (lex{}) {
  746. return retL, true
  747. }
  748. case ';':
  749. if escape || zl.quote {
  750. // Inside quotes or escaped this is legal.
  751. str[stri] = x
  752. stri++
  753. escape = false
  754. break
  755. }
  756. zl.commt = true
  757. zl.comBuf = ""
  758. if comi > 1 {
  759. // A newline was previously seen inside a comment that
  760. // was inside braces and we delayed adding it until now.
  761. com[comi] = ' ' // convert newline to space
  762. comi++
  763. }
  764. com[comi] = ';'
  765. comi++
  766. if stri > 0 {
  767. zl.comBuf = string(com[:comi])
  768. l.value = zString
  769. l.token = string(str[:stri])
  770. return *l, true
  771. }
  772. case '\r':
  773. escape = false
  774. if zl.quote {
  775. str[stri] = x
  776. stri++
  777. }
  778. // discard if outside of quotes
  779. case '\n':
  780. escape = false
  781. // Escaped newline
  782. if zl.quote {
  783. str[stri] = x
  784. stri++
  785. break
  786. }
  787. if zl.commt {
  788. // Reset a comment
  789. zl.commt = false
  790. zl.rrtype = false
  791. // If not in a brace this ends the comment AND the RR
  792. if zl.brace == 0 {
  793. zl.owner = true
  794. l.value = zNewline
  795. l.token = "\n"
  796. zl.comment = string(com[:comi])
  797. return *l, true
  798. }
  799. zl.comBuf = string(com[:comi])
  800. break
  801. }
  802. if zl.brace == 0 {
  803. // If there is previous text, we should output it here
  804. var retL lex
  805. if stri != 0 {
  806. l.value = zString
  807. l.token = string(str[:stri])
  808. if !zl.rrtype {
  809. tokenUpper := strings.ToUpper(l.token)
  810. if t, ok := StringToType[tokenUpper]; ok {
  811. zl.rrtype = true
  812. l.value = zRrtpe
  813. l.torc = t
  814. }
  815. }
  816. retL = *l
  817. }
  818. l.value = zNewline
  819. l.token = "\n"
  820. zl.comment = zl.comBuf
  821. zl.comBuf = ""
  822. zl.rrtype = false
  823. zl.owner = true
  824. if retL != (lex{}) {
  825. zl.nextL = true
  826. return retL, true
  827. }
  828. return *l, true
  829. }
  830. case '\\':
  831. // comments do not get escaped chars, everything is copied
  832. if zl.commt {
  833. com[comi] = x
  834. comi++
  835. break
  836. }
  837. // something already escaped must be in string
  838. if escape {
  839. str[stri] = x
  840. stri++
  841. escape = false
  842. break
  843. }
  844. // something escaped outside of string gets added to string
  845. str[stri] = x
  846. stri++
  847. escape = true
  848. case '"':
  849. if zl.commt {
  850. com[comi] = x
  851. comi++
  852. break
  853. }
  854. if escape {
  855. str[stri] = x
  856. stri++
  857. escape = false
  858. break
  859. }
  860. zl.space = false
  861. // send previous gathered text and the quote
  862. var retL lex
  863. if stri != 0 {
  864. l.value = zString
  865. l.token = string(str[:stri])
  866. retL = *l
  867. }
  868. // send quote itself as separate token
  869. l.value = zQuote
  870. l.token = "\""
  871. zl.quote = !zl.quote
  872. if retL != (lex{}) {
  873. zl.nextL = true
  874. return retL, true
  875. }
  876. return *l, true
  877. case '(', ')':
  878. if zl.commt {
  879. com[comi] = x
  880. comi++
  881. break
  882. }
  883. if escape || zl.quote {
  884. // Inside quotes or escaped this is legal.
  885. str[stri] = x
  886. stri++
  887. escape = false
  888. break
  889. }
  890. switch x {
  891. case ')':
  892. zl.brace--
  893. if zl.brace < 0 {
  894. l.token = "extra closing brace"
  895. l.err = true
  896. return *l, true
  897. }
  898. case '(':
  899. zl.brace++
  900. }
  901. default:
  902. escape = false
  903. if zl.commt {
  904. com[comi] = x
  905. comi++
  906. break
  907. }
  908. str[stri] = x
  909. stri++
  910. zl.space = false
  911. }
  912. }
  913. if zl.readErr != nil && zl.readErr != io.EOF {
  914. // Don't return any tokens after a read error occurs.
  915. return lex{value: zEOF}, false
  916. }
  917. var retL lex
  918. if stri > 0 {
  919. // Send remainder of str
  920. l.value = zString
  921. l.token = string(str[:stri])
  922. retL = *l
  923. if comi <= 0 {
  924. return retL, true
  925. }
  926. }
  927. if comi > 0 {
  928. // Send remainder of com
  929. l.value = zNewline
  930. l.token = "\n"
  931. zl.comment = string(com[:comi])
  932. if retL != (lex{}) {
  933. zl.nextL = true
  934. return retL, true
  935. }
  936. return *l, true
  937. }
  938. if zl.brace != 0 {
  939. l.token = "unbalanced brace"
  940. l.err = true
  941. return *l, true
  942. }
  943. return lex{value: zEOF}, false
  944. }
  945. func (zl *zlexer) Comment() string {
  946. if zl.l.err {
  947. return ""
  948. }
  949. return zl.comment
  950. }
  951. // Extract the class number from CLASSxx
  952. func classToInt(token string) (uint16, bool) {
  953. offset := 5
  954. if len(token) < offset+1 {
  955. return 0, false
  956. }
  957. class, err := strconv.ParseUint(token[offset:], 10, 16)
  958. if err != nil {
  959. return 0, false
  960. }
  961. return uint16(class), true
  962. }
  963. // Extract the rr number from TYPExxx
  964. func typeToInt(token string) (uint16, bool) {
  965. offset := 4
  966. if len(token) < offset+1 {
  967. return 0, false
  968. }
  969. typ, err := strconv.ParseUint(token[offset:], 10, 16)
  970. if err != nil {
  971. return 0, false
  972. }
  973. return uint16(typ), true
  974. }
  975. // stringToTTL parses things like 2w, 2m, etc, and returns the time in seconds.
  976. func stringToTTL(token string) (uint32, bool) {
  977. var s, i uint32
  978. for _, c := range token {
  979. switch c {
  980. case 's', 'S':
  981. s += i
  982. i = 0
  983. case 'm', 'M':
  984. s += i * 60
  985. i = 0
  986. case 'h', 'H':
  987. s += i * 60 * 60
  988. i = 0
  989. case 'd', 'D':
  990. s += i * 60 * 60 * 24
  991. i = 0
  992. case 'w', 'W':
  993. s += i * 60 * 60 * 24 * 7
  994. i = 0
  995. case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
  996. i *= 10
  997. i += uint32(c) - '0'
  998. default:
  999. return 0, false
  1000. }
  1001. }
  1002. return s + i, true
  1003. }
  1004. // Parse LOC records' <digits>[.<digits>][mM] into a
  1005. // mantissa exponent format. Token should contain the entire
  1006. // string (i.e. no spaces allowed)
  1007. func stringToCm(token string) (e, m uint8, ok bool) {
  1008. if token[len(token)-1] == 'M' || token[len(token)-1] == 'm' {
  1009. token = token[0 : len(token)-1]
  1010. }
  1011. s := strings.SplitN(token, ".", 2)
  1012. var meters, cmeters, val int
  1013. var err error
  1014. switch len(s) {
  1015. case 2:
  1016. if cmeters, err = strconv.Atoi(s[1]); err != nil {
  1017. return
  1018. }
  1019. fallthrough
  1020. case 1:
  1021. if meters, err = strconv.Atoi(s[0]); err != nil {
  1022. return
  1023. }
  1024. case 0:
  1025. // huh?
  1026. return 0, 0, false
  1027. }
  1028. ok = true
  1029. if meters > 0 {
  1030. e = 2
  1031. val = meters
  1032. } else {
  1033. e = 0
  1034. val = cmeters
  1035. }
  1036. for val > 10 {
  1037. e++
  1038. val /= 10
  1039. }
  1040. if e > 9 {
  1041. ok = false
  1042. }
  1043. m = uint8(val)
  1044. return
  1045. }
  1046. func toAbsoluteName(name, origin string) (absolute string, ok bool) {
  1047. // check for an explicit origin reference
  1048. if name == "@" {
  1049. // require a nonempty origin
  1050. if origin == "" {
  1051. return "", false
  1052. }
  1053. return origin, true
  1054. }
  1055. // require a valid domain name
  1056. _, ok = IsDomainName(name)
  1057. if !ok || name == "" {
  1058. return "", false
  1059. }
  1060. // check if name is already absolute
  1061. if IsFqdn(name) {
  1062. return name, true
  1063. }
  1064. // require a nonempty origin
  1065. if origin == "" {
  1066. return "", false
  1067. }
  1068. return appendOrigin(name, origin), true
  1069. }
  1070. func appendOrigin(name, origin string) string {
  1071. if origin == "." {
  1072. return name + origin
  1073. }
  1074. return name + "." + origin
  1075. }
  1076. // LOC record helper function
  1077. func locCheckNorth(token string, latitude uint32) (uint32, bool) {
  1078. switch token {
  1079. case "n", "N":
  1080. return LOC_EQUATOR + latitude, true
  1081. case "s", "S":
  1082. return LOC_EQUATOR - latitude, true
  1083. }
  1084. return latitude, false
  1085. }
  1086. // LOC record helper function
  1087. func locCheckEast(token string, longitude uint32) (uint32, bool) {
  1088. switch token {
  1089. case "e", "E":
  1090. return LOC_EQUATOR + longitude, true
  1091. case "w", "W":
  1092. return LOC_EQUATOR - longitude, true
  1093. }
  1094. return longitude, false
  1095. }
  1096. // "Eat" the rest of the "line"
  1097. func slurpRemainder(c *zlexer, f string) *ParseError {
  1098. l, _ := c.Next()
  1099. switch l.value {
  1100. case zBlank:
  1101. l, _ = c.Next()
  1102. if l.value != zNewline && l.value != zEOF {
  1103. return &ParseError{f, "garbage after rdata", l}
  1104. }
  1105. case zNewline:
  1106. case zEOF:
  1107. default:
  1108. return &ParseError{f, "garbage after rdata", l}
  1109. }
  1110. return nil
  1111. }
  1112. // Parse a 64 bit-like ipv6 address: "0014:4fff:ff20:ee64"
  1113. // Used for NID and L64 record.
  1114. func stringToNodeID(l lex) (uint64, *ParseError) {
  1115. if len(l.token) < 19 {
  1116. return 0, &ParseError{l.token, "bad NID/L64 NodeID/Locator64", l}
  1117. }
  1118. // There must be three colons at fixes postitions, if not its a parse error
  1119. if l.token[4] != ':' && l.token[9] != ':' && l.token[14] != ':' {
  1120. return 0, &ParseError{l.token, "bad NID/L64 NodeID/Locator64", l}
  1121. }
  1122. s := l.token[0:4] + l.token[5:9] + l.token[10:14] + l.token[15:19]
  1123. u, err := strconv.ParseUint(s, 16, 64)
  1124. if err != nil {
  1125. return 0, &ParseError{l.token, "bad NID/L64 NodeID/Locator64", l}
  1126. }
  1127. return u, nil
  1128. }