Browse Source

moar spf

tags/v0.3.1
Bob Rudis 4 years ago
parent
commit
2072f5245d
15 changed files with 523 additions and 34 deletions
  1. +5
    -3
      DESCRIPTION
  2. +16
    -0
      NAMESPACE
  3. +6
    -2
      R/gdns-package.r
  4. +30
    -7
      R/gdns.r
  5. +108
    -0
      R/spf.r
  6. +24
    -3
      README.Rmd
  7. +233
    -12
      README.md
  8. +8
    -1
      man/bulk_query.Rd
  9. +3
    -1
      man/gdns.Rd
  10. +15
    -0
      man/has_spf.Rd
  11. +21
    -0
      man/is_soft_fail.Rd
  12. +11
    -4
      man/query.Rd
  13. +24
    -0
      man/spf_ipv4s.Rd
  14. +18
    -0
      man/split_spf.Rd
  15. +1
    -1
      tests/testthat/test-gdns.R

+ 5
- 3
DESCRIPTION View File

@@ -1,6 +1,6 @@
Package: gdns
Title: Tools to Work with Google DNS Over HTTPS API
Version: 0.1.0.9000
Version: 0.2.0.9000
Authors@R: c(person("Bob", "Rudis", email = "bob@rudis.net", role = c("aut", "cre")))
Maintainer: Bob Rudis <bob@rudis.net>
Description: To address the problem of insecurity of UDP-based DNS requests,
@@ -9,7 +9,8 @@ Description: To address the problem of insecurity of UDP-based DNS requests,
between a client and a recursive resolver, and complements DNSSEC
to provide end-to-end authenticated DNS lookups. Functions that enable
querying individual requests that bulk requests that return detailed
responses and bulk requests are both provided.
responses and bulk requests are both provided. Support for reverse
lookups is also provided.
License: AGPL + file LICENSE
LazyData: true
Encoding: UTF-8
@@ -20,5 +21,6 @@ Suggests:
Imports:
httr,
jsonlite,
purrr
purrr,
stringi
RoxygenNote: 5.0.1

+ 16
- 0
NAMESPACE View File

@@ -1,9 +1,25 @@
# Generated by roxygen2: do not edit by hand

export(bulk_query)
export(has_spf)
export(is_hard_fail)
export(is_soft_fail)
export(passes_all)
export(query)
export(spf_exists)
export(spf_includes)
export(spf_ipv4s)
export(spf_ipv6s)
export(spf_ptrs)
export(split_spf)
import(httr)
importFrom(jsonlite,fromJSON)
importFrom(purrr,"%||%")
importFrom(purrr,map)
importFrom(purrr,map_df)
importFrom(purrr,safely)
importFrom(stringi,stri_enc_toutf8)
importFrom(stringi,stri_replace_all_regex)
importFrom(stringi,stri_split_fixed)
importFrom(stringi,stri_split_regex)
importFrom(stringi,stri_trim)

+ 6
- 2
R/gdns-package.r View File

@@ -10,12 +10,16 @@
#' To address this problem, Google Public DNS offers DNS resolution over an
#' encrypted HTTPS connection. DNS-over-HTTPS greatly enhances privacy and
#' security between a client and a recursive resolver, and complements DNSSEC
#' to provide end-to-end authenticated DNS lookups.#'
#' to provide end-to-end authenticated DNS lookups.\cr
#' \cr
#' Support for reverse lookups is also provided.
#'
#' @name gdns
#' @docType package
#' @author Bob Rudis (@@hrbrmstr)
#' @import httr
#' @importFrom stringi stri_split_fixed stri_split_regex stri_trim
#' stri_replace_all_regex stri_enc_toutf8
#' @importFrom jsonlite fromJSON
#' @importFrom purrr safely map map_df
#' @importFrom purrr safely map map_df %||%
NULL

+ 30
- 7
R/gdns.r View File

@@ -1,3 +1,6 @@
ipv4_regex <-
"^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$"

S_GET <- purrr::safely(GET)

#' Perform DNS over HTTPS queries using Google
@@ -20,9 +23,12 @@ S_GET <- purrr::safely(GET)
#' @param name item to lookup. Valid characters are numbers, letters, hyphen, and dot. Length
#' must be between 1 and 255. Names with escaped or non-ASCII characters
#' are not supported. Internationalized domain names must use the
#' punycode format (e.g. "\code{xn--qxam}").
#' punycode format (e.g. "\code{xn--qxam}").\cr
#' \cr If an IPv4 string is input, it will be transformed into
#' a proper format for reverse lookups.
#' @param type RR type can be represented as a number in [1, 65535] or canonical
#' string (A, aaaa, etc.)
#' string (A, aaaa, etc). More information on RR types can be
#' found \href{http://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml#dns-parameters-4}{here}.
#' @param edns_client_subnet The edns0-client-subnet option. Format is an IP
#' address with a subnet mask. Examples: \code{1.2.3.4/24},
#' \code{2001:700:300::/48}.\cr
@@ -31,13 +37,23 @@ S_GET <- purrr::safely(GET)
#' nameservers for geographic location accuracy, use
#' \code{edns_client_subnet=0.0.0.0/0}. Google Public DNS normally sends
#' approximate network information (usually replacing the last part of
#' your IPv4 address with zeroes).
#' your IPv4 address with zeroes). \code{0.0.0.0/0} is the default.
#' @return a \code{list} with the query result or \code{NULL} if an error occurred
#' @references \url{https://developers.google.com/speed/public-dns/docs/dns-over-https}
#' @export
#' @examples
#' query("rud.is")
query <- function(name, type="1", edns_client_subnet=NULL) {
#' query("microsoft.com", "MX")
#' query("google-public-dns-a.google.com", "TXT")
#' query("apple.com")
#' query("17.142.160.59", "PTR")
query <- function(name, type="1", edns_client_subnet="0.0.0.0/0") {

if (grepl(ipv4_regex, name)) {
name <- paste0(c(rev(unlist(stringi::stri_split_fixed(name, ".", 4))),
"in-addr.arpa."),
sep="", collapse=".")
}

res <- S_GET("https://dns.google.com/resolve",
query=list(name=name,
@@ -46,7 +62,10 @@ query <- function(name, type="1", edns_client_subnet=NULL) {

if (!is.null(res$result)) {
stop_for_status(res$result)
jsonlite::fromJSON(httr::content(res$result, as="text"))
txt <- httr::content(res$result, as="text")
txt <- stringi::stri_enc_toascii(txt)
txt <- stringi::stri_replace_all_regex(txt, "[[:cntrl:][:blank:]\\n ]+", " ")
jsonlite::fromJSON(txt)
} else {
NULL
}
@@ -56,13 +75,17 @@ query <- function(name, type="1", edns_client_subnet=NULL) {
#' Vectorized query, returning only answers in a data frame
#'
#' @param hosts character vector of hosts to query
#' @param type RR type (see \code{type} in \code{query()}).
#' @return \code{data.frame} of only answers (use \code{query()} for detailed responses)
#' @references \url{https://developers.google.com/speed/public-dns/docs/dns-over-https}
#' @export
#' @note this is a fairly naive function. It expects \code{Answer} to be one of the
#' return value list slots. The intent for it was to make it easier
#' to do bulk forward queries. It will get smarter in future versions.
#' @examples
#' hosts <- c("rud.is", "dds.ec", "r-project.org", "rstudio.com", "apple.com")
#' gdns::bulk_query(hosts)
bulk_query <- function(hosts) {
results <- map(hosts, gdns::query)
bulk_query <- function(hosts, type=1) {
results <- map(hosts, gdns::query, type=type)
map_df(results, "Answer")
}

+ 108
- 0
R/spf.r View File

@@ -0,0 +1,108 @@
#' Split out all SPF records in a domain's TXT record
#'
#' Given a vector of TXT records, this function will return a list of vectors
#' of all the SPF records for each. If the given TXT record is not an SPF
#' record, \code{NULL} is returned (which makes it easy to skip with \code{purrr}
#' functions).
#'
#' @param spf_rec a character vector of DNS TXT records
#' @export
split_spf <- function(spf_rec) {
purrr::map(spf_rec, .split_spf)
}

.split_spf <- function(spf_rec) {

if (has_spf(spf_rec)) {
spf_rec <- stringi::stri_trim(stringi::stri_replace_all_regex(spf_rec, '"', ""))
recs <- stri_trim(unlist(stringi::stri_split_regex(spf_rec, "\ +")))
grep("v=spf1", recs, invert=TRUE, value=TRUE)
} else {
NA_character_
}

}

#' Test for whether a DNS TXT record is an SPF record
#'
#' @param spf_rec a character vector of DNS TXT records
#' @export
has_spf <- function(spf_rec) {
grepl("v=spf1", spf_rec)
}

#' SPF "all" type test
#'
#' @param spf_rec a character vector of DNS TXT records
#' @export
is_soft_fail <- function(spf_rec) {
ret <- vector("logical", length(spf_rec))
spf_rec <- stringi::stri_trim(stringi::stri_replace_all_regex(spf_rec, '"', ""))
SPF <- which(has_spf(spf_rec))
ret[SPF] <- grepl("~all$", stringi::stri_trim(spf_rec[SPF]))
ret[!SPF] <- NA
ret
}

#' @rdname is_soft_fail
#' @export
is_hard_fail <- function(spf_rec) {
ret <- vector("logical", length(spf_rec))
spf_rec <- stringi::stri_trim(stringi::stri_replace_all_regex(spf_rec, '"', ""))
SPF <- which(has_spf(spf_rec))
ret[SPF] <- grepl("\\-all$", stringi::stri_trim(spf_rec[SPF]))
ret[!SPF] <- NA
ret
}

#' @rdname is_soft_fail
#' @export
passes_all <- function(spf_rec) {
ret <- vector("logical", length(spf_rec))
spf_rec <- stringi::stri_trim(stringi::stri_replace_all_regex(spf_rec, '"', ""))
SPF <- which(has_spf(spf_rec))
ret[SPF] <- grepl("\\+all$", stringi::stri_trim(spf_rec[SPF]))
ret[!SPF] <- NA
ret
}

#' SPF field extraction functions
#'
#' @export
spf_ipv4s <- function(spf_rec) {
purrr::map(split_spf(spf_rec), function(x) {
stringi::stri_replace_all_regex(grep("ip4", x, value=TRUE), "^ip4:", "")
})
}

#' @rdname spf_ipv4s
#' @export
spf_ipv6s <- function(spf_rec) {
purrr::map(split_spf(spf_rec), function(x) {
stringi::stri_replace_all_regex(grep("ip6", x, value=TRUE), "^ip6:", "")
})
}

#' @rdname spf_ipv4s
#' @export
spf_includes <- function(spf_rec) {
purrr::map(split_spf(spf_rec), function(x) {
stringi::stri_replace_all_regex(grep("include", x, value=TRUE), "^include:", "")
})
}

#' @rdname spf_ipv4s
#' @export
spf_ptrs <- function(spf_rec) {
purrr::map(split_spf(spf_rec), function(x) {
stringi::stri_replace_all_regex(grep("ptr", x, value=TRUE), "^ptr[:]", "")
})
}

#' @rdname spf_ipv4s
#' @export
spf_exists <- function(spf_rec) {
purrr::map(split_spf(spf_rec), function(x) {
stringi::stri_replace_all_regex(grep("exists", x, value=TRUE), "^exists:", "")
})
}

+ 24
- 3
README.Rmd View File

@@ -23,11 +23,22 @@ More info at <https://developers.google.com/speed/public-dns/docs/dns-over-https

The following functions are implemented:

- `query` : perform Google DNS query for a single host (retreives metadata & answer)
- `bulk_query` : perform bulk host queries, returning a \code{data.frame} of only answers (no metadata)
- `bulk_query`: Vectorized query, returning only answers in a data frame
- `has_spf`: Test for whether a DNS TXT record is an SPF record
- `is_hard_fail`: SPF "all" type test
- `is_soft_fail`: SPF "all" type test
- `passes_all`: SPF "all" type test
- `query`: Perform DNS over HTTPS queries using Google
- `spf_exists`: SPF field extraction functions
- `spf_includes`: SPF field extraction functions
- `spf_ipv4s`: SPF field extraction functions
- `spf_ipv6s`: SPF field extraction functions
- `spf_ptrs`: SPF field extraction functions
- `split_spf`: Split out all SPF records in a domain's TXT record

### News

- Version 0.2.0.9000 SPF stuff
- Version 0.1.0.9000 released

### Installation
@@ -60,9 +71,19 @@ date()

test_dir("tests/")

hosts <- c("rud.is", "dds.ec", "r-project.org", "rstudio.com", "apple.com")
query("rud.is")

query("microsoft.com", "MX")

query("google-public-dns-a.google.com", "TXT")

query("apple.com")

query("17.142.160.59", "PTR")

hosts <- c("rud.is", "dds.ec", "r-project.org", "rstudio.com", "apple.com")
gdns::bulk_query(hosts)

```

### Code of Conduct


+ 233
- 12
README.md View File

@@ -12,11 +12,22 @@ More info at <https://developers.google.com/speed/public-dns/docs/dns-over-https

The following functions are implemented:

- `query` : perform Google DNS query for a single host (retreives metadata & answer)
- `bulk_query` : perform bulk host queries, returning a of only answers (no metadata)
- `bulk_query`: Vectorized query, returning only answers in a data frame
- `has_spf`: Test for whether a DNS TXT record is an SPF record
- `is_hard_fail`: SPF "all" type test
- `is_soft_fail`: SPF "all" type test
- `passes_all`: SPF "all" type test
- `query`: Perform DNS over HTTPS queries using Google
- `spf_exists`: SPF field extraction functions
- `spf_includes`: SPF field extraction functions
- `spf_ipv4s`: SPF field extraction functions
- `spf_ipv6s`: SPF field extraction functions
- `spf_ptrs`: SPF field extraction functions
- `split_spf`: Split out all SPF records in a domain's TXT record

### News

- Version 0.2.0.9000 SPF stuff
- Version 0.1.0.9000 released

### Installation
@@ -32,7 +43,7 @@ library(gdns)

# current verison
packageVersion("gdns")
#> [1] '0.1.0.9000'
#> [1] '0.2.0.9000'
```

### Test Results
@@ -42,26 +53,236 @@ library(gdns)
library(testthat)

date()
#> [1] "Sat Apr 9 21:17:02 2016"
#> [1] "Sun Apr 10 14:51:46 2016"

test_dir("tests/")
#> testthat results ========================================================================================================
#> OK: 2 SKIPPED: 0 FAILED: 0

hosts <- c("rud.is", "dds.ec", "r-project.org", "rstudio.com", "apple.com")
query("rud.is")
#> $Status
#> [1] 0
#>
#> $TC
#> [1] FALSE
#>
#> $RD
#> [1] TRUE
#>
#> $RA
#> [1] TRUE
#>
#> $AD
#> [1] FALSE
#>
#> $CD
#> [1] FALSE
#>
#> $Question
#> name type
#> 1 rud.is. 1
#>
#> $Answer
#> name type TTL data
#> 1 rud.is. 1 3599 104.236.112.222
#>
#> $Additional
#> list()
#>
#> $edns_client_subnet
#> [1] "0.0.0.0/0"
#>
#> $Comment
#> [1] "Response from dns.mwebdns.net.(84.246.121.10)"

query("microsoft.com", "MX")
#> $Status
#> [1] 0
#>
#> $TC
#> [1] FALSE
#>
#> $RD
#> [1] TRUE
#>
#> $RA
#> [1] TRUE
#>
#> $AD
#> [1] FALSE
#>
#> $CD
#> [1] FALSE
#>
#> $Question
#> name type
#> 1 microsoft.com. 15
#>
#> $Answer
#> name type TTL data
#> 1 microsoft.com. 15 2054 10 microsoft-com.mail.protection.outlook.com.
#>
#> $Additional
#> list()
#>
#> $edns_client_subnet
#> [1] "0.0.0.0/0"

query("google-public-dns-a.google.com", "TXT")
#> $Status
#> [1] 0
#>
#> $TC
#> [1] FALSE
#>
#> $RD
#> [1] TRUE
#>
#> $RA
#> [1] TRUE
#>
#> $AD
#> [1] FALSE
#>
#> $CD
#> [1] FALSE
#>
#> $Question
#> name type
#> 1 google-public-dns-a.google.com. 16
#>
#> $Answer
#> name type TTL data
#> 1 google-public-dns-a.google.com. 16 21599 "http://xkcd.com/1361/"
#>
#> $Additional
#> list()
#>
#> $edns_client_subnet
#> [1] "0.0.0.0/0"
#>
#> $Comment
#> [1] "Response from 216.239.38.10"

query("apple.com")
#> $Status
#> [1] 0
#>
#> $TC
#> [1] FALSE
#>
#> $RD
#> [1] TRUE
#>
#> $RA
#> [1] TRUE
#>
#> $AD
#> [1] FALSE
#>
#> $CD
#> [1] FALSE
#>
#> $Question
#> name type
#> 1 apple.com. 1
#>
#> $Answer
#> name type TTL data
#> 1 apple.com. 1 1119 17.172.224.47
#> 2 apple.com. 1 1119 17.178.96.59
#> 3 apple.com. 1 1119 17.142.160.59
#>
#> $Additional
#> list()
#>
#> $edns_client_subnet
#> [1] "0.0.0.0/0"

query("17.142.160.59", "PTR")
#> $Status
#> [1] 0
#>
#> $TC
#> [1] FALSE
#>
#> $RD
#> [1] TRUE
#>
#> $RA
#> [1] TRUE
#>
#> $AD
#> [1] FALSE
#>
#> $CD
#> [1] FALSE
#>
#> $Question
#> name type
#> 1 59.160.142.17.in-addr.arpa. 12
#>
#> $Answer
#> name type TTL data
#> 1 59.160.142.17.in-addr.arpa. 12 1134 alchemysynth.com.
#> 2 59.160.142.17.in-addr.arpa. 12 1134 openni.org.
#> 3 59.160.142.17.in-addr.arpa. 12 1134 swell.am.
#> 4 59.160.142.17.in-addr.arpa. 12 1134 appleweb.net.
#> 5 59.160.142.17.in-addr.arpa. 12 1134 apple.com.
#> 6 59.160.142.17.in-addr.arpa. 12 1134 pv-apple-com.apple.com.
#> 7 59.160.142.17.in-addr.arpa. 12 1134 apple.by.
#> 8 59.160.142.17.in-addr.arpa. 12 1134 airtunes.info.
#> 9 59.160.142.17.in-addr.arpa. 12 1134 applecentre.info.
#> 10 59.160.142.17.in-addr.arpa. 12 1134 applecomputerinc.info.
#> 11 59.160.142.17.in-addr.arpa. 12 1134 appleexpo.info.
#> 12 59.160.142.17.in-addr.arpa. 12 1134 applemasters.info.
#> 13 59.160.142.17.in-addr.arpa. 12 1134 applepay.info.
#> 14 59.160.142.17.in-addr.arpa. 12 1134 applepaymerchantsupplies.info.
#> 15 59.160.142.17.in-addr.arpa. 12 1134 applepaysupplies.info.
#> 16 59.160.142.17.in-addr.arpa. 12 1134 applescript.info.
#> 17 59.160.142.17.in-addr.arpa. 12 1134 appleshare.info.
#> 18 59.160.142.17.in-addr.arpa. 12 1134 macosx.info.
#> 19 59.160.142.17.in-addr.arpa. 12 1134 powerbook.info.
#> 20 59.160.142.17.in-addr.arpa. 12 1134 powermac.info.
#> 21 59.160.142.17.in-addr.arpa. 12 1134 quicktimelive.info.
#> 22 59.160.142.17.in-addr.arpa. 12 1134 quicktimetv.info.
#> 23 59.160.142.17.in-addr.arpa. 12 1134 sherlock.info.
#> 24 59.160.142.17.in-addr.arpa. 12 1134 shopdifferent.info.
#> 25 59.160.142.17.in-addr.arpa. 12 1134 skyvines.info.
#> 26 59.160.142.17.in-addr.arpa. 12 1134 ubnw.info.
#> 27 59.160.142.17.in-addr.arpa. 12 1134 webobjects.info.
#> 28 59.160.142.17.in-addr.arpa. 12 1134 yessql.info.
#> 29 59.160.142.17.in-addr.arpa. 12 1134 ripmixburn.com.
#> 30 59.160.142.17.in-addr.arpa. 12 1134 apples-msk.ru.
#> 31 59.160.142.17.in-addr.arpa. 12 1134 icloud.se.
#> 32 59.160.142.17.in-addr.arpa. 12 1134 icloud.es.
#> 33 59.160.142.17.in-addr.arpa. 12 1134 icloud.om.
#> 34 59.160.142.17.in-addr.arpa. 12 1134 icloudo.com.
#> 35 59.160.142.17.in-addr.arpa. 12 1134 icloud.ch.
#> 36 59.160.142.17.in-addr.arpa. 12 1134 icloud.fr.
#> 37 59.160.142.17.in-addr.arpa. 12 1134 icloude.com.
#> 38 59.160.142.17.in-addr.arpa. 12 1134 camelspaceeffect.com.
#> 39 59.160.142.17.in-addr.arpa. 12 1134 camelphat.com.
#>
#> $Additional
#> list()
#>
#> $edns_client_subnet
#> [1] "0.0.0.0/0"

hosts <- c("rud.is", "dds.ec", "r-project.org", "rstudio.com", "apple.com")
gdns::bulk_query(hosts)
#> Source: local data frame [7 x 4]
#>
#> name type TTL data
#> (chr) (int) (int) (chr)
#> 1 rud.is. 1 710 104.236.112.222
#> 2 dds.ec. 1 280 162.243.111.4
#> 3 r-project.org. 1 6410 137.208.57.37
#> 4 rstudio.com. 1 71 45.79.156.36
#> 5 apple.com. 1 3290 17.172.224.47
#> 6 apple.com. 1 3290 17.178.96.59
#> 7 apple.com. 1 3290 17.142.160.59
#> 1 rud.is. 1 3598 104.236.112.222
#> 2 dds.ec. 1 299 162.243.111.4
#> 3 r-project.org. 1 7177 137.208.57.37
#> 4 rstudio.com. 1 3599 45.79.156.36
#> 5 apple.com. 1 1102 17.172.224.47
#> 6 apple.com. 1 1102 17.178.96.59
#> 7 apple.com. 1 1102 17.142.160.59
```

### Code of Conduct


+ 8
- 1
man/bulk_query.Rd View File

@@ -4,10 +4,12 @@
\alias{bulk_query}
\title{Vectorized query, returning only answers in a data frame}
\usage{
bulk_query(hosts)
bulk_query(hosts, type = 1)
}
\arguments{
\item{hosts}{character vector of hosts to query}

\item{type}{RR type (see \code{type} in \code{query()}).}
}
\value{
\code{data.frame} of only answers (use \code{query()} for detailed responses)
@@ -15,6 +17,11 @@ bulk_query(hosts)
\description{
Vectorized query, returning only answers in a data frame
}
\note{
this is a fairly naive function. It expects \code{Answer} to be one of the
return value list slots. The intent for it was to make it easier
to do bulk forward queries. It will get smarter in future versions.
}
\examples{
hosts <- c("rud.is", "dds.ec", "r-project.org", "rstudio.com", "apple.com")
gdns::bulk_query(hosts)


+ 3
- 1
man/gdns.Rd View File

@@ -16,7 +16,9 @@ often incorporate additional protection.\cr
To address this problem, Google Public DNS offers DNS resolution over an
encrypted HTTPS connection. DNS-over-HTTPS greatly enhances privacy and
security between a client and a recursive resolver, and complements DNSSEC
to provide end-to-end authenticated DNS lookups.#'
to provide end-to-end authenticated DNS lookups.\cr
\cr
Support for reverse lookups is also provided.
}
\author{
Bob Rudis (@hrbrmstr)


+ 15
- 0
man/has_spf.Rd View File

@@ -0,0 +1,15 @@
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/spf.r
\name{has_spf}
\alias{has_spf}
\title{Test for whether a DNS TXT record is an SPF record}
\usage{
has_spf(spf_rec)
}
\arguments{
\item{spf_rec}{a character vector of DNS TXT records}
}
\description{
Test for whether a DNS TXT record is an SPF record
}


+ 21
- 0
man/is_soft_fail.Rd View File

@@ -0,0 +1,21 @@
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/spf.r
\name{is_soft_fail}
\alias{is_hard_fail}
\alias{is_soft_fail}
\alias{passes_all}
\title{SPF "all" type test}
\usage{
is_soft_fail(spf_rec)

is_hard_fail(spf_rec)

passes_all(spf_rec)
}
\arguments{
\item{spf_rec}{a character vector of DNS TXT records}
}
\description{
SPF "all" type test
}


+ 11
- 4
man/query.Rd View File

@@ -4,16 +4,19 @@
\alias{query}
\title{Perform DNS over HTTPS queries using Google}
\usage{
query(name, type = "1", edns_client_subnet = NULL)
query(name, type = "1", edns_client_subnet = "0.0.0.0/0")
}
\arguments{
\item{name}{item to lookup. Valid characters are numbers, letters, hyphen, and dot. Length
must be between 1 and 255. Names with escaped or non-ASCII characters
are not supported. Internationalized domain names must use the
punycode format (e.g. "\code{xn--qxam}").}
punycode format (e.g. "\code{xn--qxam}").\cr
\cr If an IPv4 string is input, it will be transformed into
a proper format for reverse lookups.}

\item{type}{RR type can be represented as a number in [1, 65535] or canonical
string (A, aaaa, etc.)}
string (A, aaaa, etc). More information on RR types can be
found \href{http://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml#dns-parameters-4}{here}.}

\item{edns_client_subnet}{The edns0-client-subnet option. Format is an IP
address with a subnet mask. Examples: \code{1.2.3.4/24},
@@ -23,7 +26,7 @@ not want any part of your IP address to be sent to authoritative
nameservers for geographic location accuracy, use
\code{edns_client_subnet=0.0.0.0/0}. Google Public DNS normally sends
approximate network information (usually replacing the last part of
your IPv4 address with zeroes).}
your IPv4 address with zeroes). \code{0.0.0.0/0} is the default.}
}
\value{
a \code{list} with the query result or \code{NULL} if an error occurred
@@ -47,6 +50,10 @@ To perform vectorized queries with only answers (and no metadata) use
}
\examples{
query("rud.is")
query("microsoft.com", "MX")
query("google-public-dns-a.google.com", "TXT")
query("apple.com")
query("17.142.160.59", "PTR")
}
\references{
\url{https://developers.google.com/speed/public-dns/docs/dns-over-https}


+ 24
- 0
man/spf_ipv4s.Rd View File

@@ -0,0 +1,24 @@
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/spf.r
\name{spf_ipv4s}
\alias{spf_exists}
\alias{spf_includes}
\alias{spf_ipv4s}
\alias{spf_ipv6s}
\alias{spf_ptrs}
\title{SPF field extraction functions}
\usage{
spf_ipv4s(spf_rec)

spf_ipv6s(spf_rec)

spf_includes(spf_rec)

spf_ptrs(spf_rec)

spf_exists(spf_rec)
}
\description{
SPF field extraction functions
}


+ 18
- 0
man/split_spf.Rd View File

@@ -0,0 +1,18 @@
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/spf.r
\name{split_spf}
\alias{split_spf}
\title{Split out all SPF records in a domain's TXT record}
\usage{
split_spf(spf_rec)
}
\arguments{
\item{spf_rec}{a character vector of DNS TXT records}
}
\description{
Given a vector of TXT records, this function will return a list of vectors
of all the SPF records for each. If the given TXT record is not an SPF
record, \code{NULL} is returned (which makes it easy to skip with \code{purrr}
functions).
}


+ 1
- 1
tests/testthat/test-gdns.R View File

@@ -1,7 +1,7 @@
context("basic functionality")
test_that("we can do something", {

expect_that(length(gdns::query("example.com")), equals(8))
expect_that(length(gdns::query("example.com")), equals(10))

doms <- c("example.com", "example.org", "example.net")
qry <- gdns::bulk_query(doms)


Loading…
Cancel
Save