scan.go 29 KB

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