mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: David Howells <dhowells@redhat.com>
To: smfrench@gmail.com, jlayton@redhat.com
Cc: linux-fsdevel@vger.kernel.org, linux-cifs@vger.kernel.org,
	linux-afs@lists.infradead.org, linux-kernel@vger.kernel.org,
	Wang Lei <wang840925@gmail.com>,
	David Howells <dhowells@redhat.com>
Subject: [PATCH 5/6] DNS: Implement option parsing on dns_resolver results
Date: Thu, 22 Jul 2010 18:33:11 +0100	[thread overview]
Message-ID: <20100722173311.1512.10569.stgit@warthog.procyon.org.uk> (raw)
In-Reply-To: <20100722173251.1512.29858.stgit@warthog.procyon.org.uk>

From: Wang Lei <wang840925@gmail.com>

When the dns_resolver upcall program packages results and instantiates its key
with them, the offered data may have a number of options appended to it.  Each
option is of the form:

	#key=value

This implements an option by which the key's expiry time can be set from the
DNS TTL datum:

	#expiry=<nnn>

where <nnn> is a time_t value.

Signed-off-by: Wang Lei <wang840925@gmail.com>
Signed-off-by: David Howells <dhowells@redhat.com>
---

 net/dns_resolver/dns_key.c |   85 ++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 78 insertions(+), 7 deletions(-)

diff --git a/net/dns_resolver/dns_key.c b/net/dns_resolver/dns_key.c
index 1b1b411..02c7336 100644
--- a/net/dns_resolver/dns_key.c
+++ b/net/dns_resolver/dns_key.c
@@ -42,6 +42,8 @@ MODULE_PARM_DESC(debug, "DNS Resolver debugging mask");
 
 const struct cred *dns_resolver_cache;
 
+#define	DNS_EXPIRY_OPTION	"expiry_time"
+
 /*
  * Instantiate a user defined key for dns_resolver.
  *
@@ -50,17 +52,26 @@ const struct cred *dns_resolver_cache;
  *
  * If the data contains a '#' characters, then we take the clause after each
  * one to be an option of the form 'key=value'.  The actual data of interest is
- * the string leading up to the first '#'.  For instance:
+ * the string leading up to the first '#'.
+ *
+ * The only option currently supported is the expiry time of the key, which can
+ * be set from the TTL field of the DNS record.  The value should be a time_t
+ * time.
+ *
+ * For instance:
+ *
+ *        "ip1,ip2,...#expiry_time=123"
  *
- *        "ip1,ip2,...#foo=bar"
+ * the expiry time of the data is 123 and the data starts after '#'.
  */
 static int
 dns_resolver_instantiate(struct key *key, const void *_data, size_t datalen)
 {
 	struct user_key_payload *upayload;
+	unsigned long expiry = 0;
 	int ret;
 	size_t result_len = 0;
-	const char *data = _data, *opt;
+	const char *data = _data, *end, *opt;
 
 	kenter("%%%d,%s,'%s',%zu",
 	       key->serial, key->description, data, datalen);
@@ -70,13 +81,65 @@ dns_resolver_instantiate(struct key *key, const void *_data, size_t datalen)
 	datalen--;
 
 	/* deal with any options embedded in the data */
-	opt = memchr(data, '#', datalen);
+	end = data + datalen - 1;
+	opt = memchr(data, '#', datalen - 1);
 	if (!opt) {
-		kdebug("no options currently supported");
-		return -EINVAL;
+		/* no options: the entire data is the result */
+		kdebug("no options");
+		result_len = datalen - 1;
+	} else {
+		result_len = opt - data;
+		opt++;
+		kdebug("options: '%s'", opt);
+		do {
+			const char *next_opt, *eq;
+			int opt_len, opt_nlen, opt_vlen, tmp;
+
+			next_opt = memchr(opt, '#', end - opt) ?: end;
+			opt_len = next_opt - opt;
+			if (!opt_len) {
+				printk(KERN_WARNING
+				       "Empty option to dnsresolver key %d\n",
+				       key->serial);
+				return -EINVAL;
+			}
+
+			eq = memchr(opt, '=', opt_len) ?: end;
+			opt_nlen = eq - opt;
+			eq++;
+			opt_vlen = next_opt - eq; /* will be -1 if no value */
+
+			tmp = opt_vlen >= 0 ? opt_vlen : 0;
+			kdebug("option '%*.*s' val '%*.*s'",
+			       opt_nlen, opt_nlen, opt, tmp, tmp, eq);
+
+			/* see if it's the expiry time */
+			if (opt_nlen == sizeof(DNS_EXPIRY_OPTION) - 1 &&
+			    memcmp(opt, DNS_EXPIRY_OPTION, opt_nlen) == 0) {
+				kdebug("expiry time option");
+				if (opt_vlen <= 0)
+					goto bad_option_value;
+
+				ret = strict_strtoul(eq, 10, &expiry);
+				if (ret < 0)
+					goto bad_option_value;
+				kdebug("expiry time = %lu", expiry);
+				goto next_option;
+			}
+
+		bad_option_value:
+			printk(KERN_WARNING
+			       "Option '%*.*s' to dnsresolver key %d:"
+			       " bad/missing value\n",
+			       opt_nlen, opt_nlen, opt, key->serial);
+			return -EINVAL;
+
+		next_option:
+			opt = next_opt + 1;
+		} while (opt < end);
 	}
 
-	result_len = datalen;
+	kdebug("store result");
 	ret = key_payload_reserve(key, result_len);
 	if (ret < 0)
 		return -EINVAL;
@@ -87,11 +150,19 @@ dns_resolver_instantiate(struct key *key, const void *_data, size_t datalen)
 		return -ENOMEM;
 	}
 
+	/* attach the data */
 	upayload->datalen = result_len;
 	memcpy(upayload->data, data, result_len);
 	upayload->data[result_len] = '\0';
 	rcu_assign_pointer(key->payload.data, upayload);
 
+	/* if we were given an expiry time, then try to apply it */
+	kdebug("expiry %lu [%lu]", expiry, key->expiry);
+	if (expiry && (key->expiry == 0 || expiry < key->expiry)) {
+		kdebug("set expiry to %ld hence", expiry - get_seconds());
+		key->expiry = expiry;
+	}
+
 	kleave(" = 0");
 	return 0;
 }


  parent reply	other threads:[~2010-07-22 17:33 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-07-22 17:32 [PATCH 1/6] KEYS: Authorise keyctl_set_timeout() on a key if we have its authorisation key David Howells
2010-07-22 17:32 ` [PATCH 2/6] CIFS: Fix a malicious redirect problem in the DNS lookup code David Howells
2010-07-22 17:33 ` [PATCH 3/6] CIFS: Make cifs_convert_address() take a const src pointer and a length David Howells
2010-07-22 17:47   ` Jeff Layton
2010-08-04  4:21   ` Steve French
2010-07-22 17:33 ` [PATCH 4/6] DNS: Separate out CIFS DNS Resolver code David Howells
2010-07-22 17:33 ` David Howells [this message]
2010-07-22 17:33 ` [PATCH 6/6] DNS: Make AFS go to the DNS for AFSDB records for unknown cells David Howells
2010-07-22 17:34 ` [PATCH 1/6] KEYS: Authorise keyctl_set_timeout() on a key if we have its authorisation key David Howells

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20100722173311.1512.10569.stgit@warthog.procyon.org.uk \
    --to=dhowells@redhat.com \
    --cc=jlayton@redhat.com \
    --cc=linux-afs@lists.infradead.org \
    --cc=linux-cifs@vger.kernel.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=smfrench@gmail.com \
    --cc=wang840925@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®