From mike.patnode at centrify.com Wed Oct 1 14:03:44 2008 From: mike.patnode at centrify.com (Mike Patnode) Date: Wed, 1 Oct 2008 11:03:44 -0700 Subject: telnet & ftp official status In-Reply-To: <8763od9w6i.fsf@windlord.stanford.edu> References: <20080918000446.GA5266@sun.com><73708652-DDDB-4402-B058-69B5156D121F@mit.edu><20080919151016.GC1875@Sun.COM><3917C005-FA40-41DF-828D-026E9139E481@kth.se><200809191608.m8JG87D7021184@raisinbran.srv.cs.cmu.edu><20080919210411.GD1875@Sun.COM> <8763od9w6i.fsf@windlord.stanford.edu> Message-ID: We also have added a number of fixes to the these utilities as well as the core API. Our changes are against the 1.4.3 source base: Valgrind/Coverity fixes Referral Processing (client side only) Force TCP configuration Credentials from skey: krb5_get_init_creds_skey() Malloc/Free API for key creation APIs (allow encryption keys to be kept in mlock'd memory) Microsoft S4U extension implementation (client side only) ftp/telnet PAM/LAM support AIX port Salt retrieval API We also have implemented a secure service name canonicalization mechanism, but since it's Active Directory specific, I don't think it's generally useful to other folks. I'd like to get as many of these changes back into the distribution as possible (with the complete understanding that some may not be included). I know the Consortium recently purchased Coverity, and our fixes could certainly save quite a bit of time there. We've analyzed and fixed about 200 items identified by Coverity in just the libraries and clients. So the question is, what's the best way to deliver these changes back upstream? I suppose we need to follow the formal proposal process for the API and feature changes. The question is do you want the diffs for the Coverity & Valgrind issues against the 1.4.3 base, or do you just want to wait until we do our 1.6 port? mp -----Original Message----- From: Russ Allbery [mailto:rra at stanford.edu] Sent: Tuesday, September 30, 2008 2:11 PM To: Tom Yu Cc: Mike Patnode; MIT Kerberos Dev List Subject: Re: telnet & ftp official status Tom Yu writes: > We need volunteers to maintain the applications if we are to remove them > from the main distribution. Russ Allbery has expressed a willingness to > do so in the past. Russ, are you still willing to do this? Is anyone > else willing to help out? I'm still willing to help maintain Kerberos rlogin, rsh, and rcp. I think they're simpler and easier to maintain than ssh, and they're also less-well-known and therefore not as much of an attack target. It may be that I'll slowly change my mind and eventually switch entirely to using ssh, particularly given the firewall issues with the rsh protocol, but I still find them convenient. However, I have very limited amounts of time to look after them (for example, I've not managed to do more than read through the patches for PAM support). So while I'm willing to help, I'm not sure how much time I'll realistically have and how much work I'll be able to put into them. I have no personal interest in Kerberos telnet or ftp. We never used Kerberos ftp at Stanford and haven't used Kerberos telnet in years. I'm happy to help generally support a build infrastructure including those, but won't have any time to make code changes in those applications in particular. I'm separately strongly interested in making sure ksu continues to be available and works, although I know it's not part of the apps tree and is something of a separate issue. -- Russ Allbery (rra at stanford.edu) From ghudson at MIT.EDU Wed Oct 1 15:44:04 2008 From: ghudson at MIT.EDU (ghudson@MIT.EDU) Date: Wed, 1 Oct 2008 15:44:04 -0400 (EDT) Subject: Realm lookups again Message-ID: <200810011944.m91Ji4fe015125@outgoing-legacy.mit.edu> I've been asked to look at https://krbdev.mit.edu/rt/Ticket/Display.html?id=6031 which is the patch from Mark Phalan at Sun to implement new algorithms for determining the default domain and the domain of a realm. I've reviewed some mailing list conversations from April and July pertaining to the issue. I have two questions for the list related to the patch: 1. Right now we have some DNS support for determining default realms and host realms (using _kerberos.domain TXT records, not heuristics), but it's off by default. The Sun patch does its DNS heuristics by default (in fact, precisely when dns_lookup_realm is false). Sam suggested that there are security issues if an attacker is able to forge the default realm, such as possibly convincing ksu not to perform a keytab lookup. Is there any way to resolve the desire for zero-configuration with the security concern about using DNS for default realm determination? 2. To use our shiny new DNS host->realm heuristic for the local default realm, we need a list of domain names to apply the heuristic to. The patch iterates over two lists of domain names: * The result of res_gethostbyaddr on each interface IP address * Each entry in the DNS search path I have concerns about the portability of this code as supplied, and more generally about our ability to portably determine the DNS search path. Would it be sufficient to canonicalize the result of gethostname() and apply the heuristic to that? (A brief introduction for those wondering who I am: I've been hired into the Kerberos consortium starting this week. I have some familiarity with the krb5 source base going back a decade or so but I'm not an expert. My work will likely focus on improving the Kerberos development process in several ways.) From ghudson at MIT.EDU Wed Oct 1 16:01:32 2008 From: ghudson at MIT.EDU (Greg Hudson) Date: Wed, 01 Oct 2008 16:01:32 -0400 Subject: telnet & ftp official status In-Reply-To: References: <20080918000446.GA5266@sun.com> <73708652-DDDB-4402-B058-69B5156D121F@mit.edu> <20080919151016.GC1875@Sun.COM> <3917C005-FA40-41DF-828D-026E9139E481@kth.se> <200809191608.m8JG87D7021184@raisinbran.srv.cs.cmu.edu> <20080919210411.GD1875@Sun.COM> <8763od9w6i.fsf@windlord.stanford.edu> Message-ID: <1222891292.6796.47.camel@error-messages.mit.edu> On Wed, 2008-10-01 at 11:03 -0700, Mike Patnode wrote: > So the question is, what's the best way to deliver these changes back > upstream? I suppose we need to follow the formal proposal process for > the API and feature changes. We discussed this process a bit yesterday. It's okay to informally discuss an API or feature change on the list before you've assembled the complete project proposal with detailed design and API documentation and so on. That way if it turns out we're not interested in a change, you haven't gone through the whole rigamarole for nothing. There downside is if the discussion peters out or rejects the proposal, there is no discoverable artifact left behind, only a thread in the mailing list archive which will quickly get lost. When I get a bit more settled, I will think about how best to record information about "non-projects" so that they can be referred to later, either using RT or the wiki. > The question is do you want the diffs for > the Coverity & Valgrind issues against the 1.4.3 base, or do you just > want to wait until we do our 1.6 port? If the goal is to save effort on our end by avoiding duplicate work, then we'll want patches against the most recent Kerberos source code--ideally the trunk. Also, it's easiest to review patches when they are logically separated. I don't want 200 separate patches for 200 defects, but if they could be collected into categories (like "eliminate memory leaks") it will make my life easier. Based on a piece of mail from Tom in July, I believe our recommended method for delivering patches from non-commiters is to send mail to krb5-bugs at mit.edu to create a ticket in RT, including patches in attachments. Finally, if in any of your analysis you uncovered evidence of an exploitable security issue, we'd like to hear about it in (ideally PGP-encrypted) email to krbcore-security at mit.edu. My experience is that most Coverity-discovered defects are not security issues, but there may be a few hidden in there. And, thank you! From Nicolas.Williams at sun.com Wed Oct 1 16:28:03 2008 From: Nicolas.Williams at sun.com (Nicolas Williams) Date: Wed, 1 Oct 2008 15:28:03 -0500 Subject: Realm lookups again In-Reply-To: <200810011944.m91Ji4fe015125@outgoing-legacy.mit.edu> References: <200810011944.m91Ji4fe015125@outgoing-legacy.mit.edu> Message-ID: <20081001202803.GN1157@Sun.COM> On Wed, Oct 01, 2008 at 03:44:04PM -0400, ghudson at MIT.EDU wrote: > I've been asked to look at > https://krbdev.mit.edu/rt/Ticket/Display.html?id=6031 which is the > patch from Mark Phalan at Sun to implement new algorithms for > determining the default domain and the domain of a realm. I've > reviewed some mailing list conversations from April and July > pertaining to the issue. > > I have two questions for the list related to the patch: > > 1. Right now we have some DNS support for determining default realms > and host realms (using _kerberos.domain TXT records, not heuristics), > but it's off by default. The Sun patch does its DNS heuristics by > default (in fact, precisely when dns_lookup_realm is false). Sam > suggested that there are security issues if an attacker is able to > forge the default realm, such as possibly convincing ksu not to > perform a keytab lookup. The heuristic in the ticket does not depend on _kerberos.domain TXT RRs, nor does it depend on DNS for the (lookup_kdcs(realm) part if DNS lookups for KDCs are not enabled. I can't see the patch, and I don't think this is in OpenSolaris, so I can't speak to what's in the patch. For the host->realm heuristic in the ticket there is an attack in that the ability to spoof NXDOMAIN replies can cause a client to think that a host's realm is one that is higher up in the chain. But this is only true if DNS lookups of KDCs is enabled. The heuristic host2realm(foo.bar.example.com) can return BAR.EXAMPLE.COM or EXAMPLE.COM, so an NXDOMAIN spoof attack on lookup_kdcs(BAR.EXAMPLE.COM) can force the heuristic to return EXAMPLE.COM. The severity of such an attack depends on whether you trust EXAMPLE.COM not to create host-based principals for hosts in bar.example.com. Now, with this heuristic this is a determination of trust that one would have to make for every domain/realm. It's a pretty good bet that sub-domain/sub-realm relationships imply that that the child domain/realm trusts the parent not to attack it willfully. "Willfully" is a key word there; the parent might be compromised and forced to attack the child. Enabling DNS lookups of KDCs does make it easier to attack PA-ENC-TIMESTAMP, something that is much more of a concern for me (of course, one could use DNS for lookup_kdcs() in the host2realm() path, but not in the AS exchange path). > Is there any way to resolve the desire for zero-configuration with the > security concern about using DNS for default realm determination? I think an interesting question is where this host2realm() heuristic should stop by default. If you make it stop at (label_count(host.fqdn) - 1) then there's no possibility of spoofing, but in the above example you'd need a domain_realm entry if BAR.EXAMPLE.COM does not exist. So you can have this heuristic on but with a default tunable that makes it immune to NXDOMAIN spoofing. A realm-join-time heuristic could also be added where the client can see for itself that the realm is not a direct mapping of its domain. "I'm in bar.example.com but my realm is EXAMPLE.COM, so assume that there's no sub-realms of EXAMPLE.COM and create a suitable domain_realm relation." > 2. To use our shiny new DNS host->realm heuristic for the local > default realm, we need a list of domain names to apply the heuristic > to. The patch iterates over two lists of domain names: > > * The result of res_gethostbyaddr on each interface IP address > * Each entry in the DNS search path > > I have concerns about the portability of this code as supplied, and > more generally about our ability to portably determine the DNS search > path. MIT krb5 already has plenty of #ifdef'ed code for things like interface address lookups, and already uses the BIND 8 resolver C interfaces, and those are pretty much universal in the Unix/Linux world (including the default domainname and the search list). I don't see what could be added here that would change that situation. > Would it be sufficient to canonicalize the result of gethostname() and > apply the heuristic to that? Quite possibly, but the canonicalization would require access to at least a default domainname from the DNS resolver. It also would be sufficient to determine the default realm from the host's keytab entries, if it has any, at realm-join time. > (A brief introduction for those wondering who I am: I've been hired > into the Kerberos consortium starting this week. I have some > familiarity with the krb5 source base going back a decade or so but > I'm not an expert. My work will likely focus on improving the > Kerberos development process in several ways.) I saw the notice today. Congratulations! Nico -- From raeburn at MIT.EDU Wed Oct 1 17:14:25 2008 From: raeburn at MIT.EDU (Ken Raeburn) Date: Wed, 1 Oct 2008 17:14:25 -0400 Subject: Realm lookups again In-Reply-To: <20081001202803.GN1157@Sun.COM> References: <200810011944.m91Ji4fe015125@outgoing-legacy.mit.edu> <20081001202803.GN1157@Sun.COM> Message-ID: <67A132C7-1992-42A6-A447-919153373D26@mit.edu> On Oct 1, 2008, at 16:28, Nicolas Williams wrote: > On Wed, Oct 01, 2008 at 03:44:04PM -0400, ghudson at MIT.EDU wrote: >> I've been asked to look at >> https://krbdev.mit.edu/rt/Ticket/Display.html?id=6031 which is the >> patch from Mark Phalan at Sun to implement new algorithms for > The heuristic in the ticket does not depend on _kerberos.domain TXT > RRs, > nor does it depend on DNS for the (lookup_kdcs(realm) part if DNS > lookups for KDCs are not enabled. I can't see the patch, and I don't > think this is in OpenSolaris, so I can't speak to what's in the patch. Does https not work for you? If not, plain http should get you in. Ken From Nicolas.Williams at sun.com Wed Oct 1 17:19:05 2008 From: Nicolas.Williams at sun.com (Nicolas Williams) Date: Wed, 1 Oct 2008 16:19:05 -0500 Subject: Realm lookups again In-Reply-To: <67A132C7-1992-42A6-A447-919153373D26@mit.edu> References: <200810011944.m91Ji4fe015125@outgoing-legacy.mit.edu> <20081001202803.GN1157@Sun.COM> <67A132C7-1992-42A6-A447-919153373D26@mit.edu> Message-ID: <20081001211905.GW1157@Sun.COM> On Wed, Oct 01, 2008 at 05:14:25PM -0400, Ken Raeburn wrote: > On Oct 1, 2008, at 16:28, Nicolas Williams wrote: > >On Wed, Oct 01, 2008 at 03:44:04PM -0400, ghudson at MIT.EDU wrote: > >>I've been asked to look at > >>https://krbdev.mit.edu/rt/Ticket/Display.html?id=6031 which is the > >>patch from Mark Phalan at Sun to implement new algorithms for > > >The heuristic in the ticket does not depend on _kerberos.domain TXT > >RRs, > >nor does it depend on DNS for the (lookup_kdcs(realm) part if DNS > >lookups for KDCs are not enabled. I can't see the patch, and I don't > >think this is in OpenSolaris, so I can't speak to what's in the patch. > > Does https not work for you? If not, plain http should get you in. Oh, sorry, the link to the patch was too far to the right and I hadn't noticed the need to scroll to the right (the text all fit without scrolling). Excuse my blindness :) From jhutz at cmu.edu Wed Oct 1 18:14:21 2008 From: jhutz at cmu.edu (Jeffrey Hutzelman) Date: Wed, 01 Oct 2008 18:14:21 -0400 Subject: Realm lookups again In-Reply-To: <200810012036.m91KafBV010554@raisinbran.srv.cs.cmu.edu> References: <200810011944.m91Ji4fe015125@outgoing-legacy.mit.edu> <200810012036.m91KafBV010554@raisinbran.srv.cs.cmu.edu> Message-ID: --On Wednesday, October 01, 2008 03:28:03 PM -0500 Nicolas Williams wrote: > It's a pretty good bet that sub-domain/sub-realm relationships imply > that that the child domain/realm trusts the parent not to attack it > willfully. "Willfully" is a key word there; the parent might be > compromised and forced to attack the child. I'm not sure this is true. It's entirely possible that a large enterprise has a smaller core of trusted services which live in a separate realm, not operated by the same people who operate the top-level realm, and which does not trust the top-level realm. Think of a security group within a large company, or a large legal or financial firm with a small group that lives behind a Chinese wall, or a government contractor with a group that does classified work. I'm nervous about making the assumption that organizational structure implies trust relationships. It is very common to create smaller organizational units which are either unusually trusted or unusually distrusted compared to the rest of the organization. -- Jeff From Nicolas.Williams at sun.com Wed Oct 1 18:21:34 2008 From: Nicolas.Williams at sun.com (Nicolas Williams) Date: Wed, 1 Oct 2008 17:21:34 -0500 Subject: Realm lookups again In-Reply-To: References: <200810011944.m91Ji4fe015125@outgoing-legacy.mit.edu> <200810012036.m91KafBV010554@raisinbran.srv.cs.cmu.edu> Message-ID: <20081001222134.GE1157@Sun.COM> On Wed, Oct 01, 2008 at 06:14:21PM -0400, Jeffrey Hutzelman wrote: > --On Wednesday, October 01, 2008 03:28:03 PM -0500 Nicolas Williams > wrote: > > >It's a pretty good bet that sub-domain/sub-realm relationships imply > >that that the child domain/realm trusts the parent not to attack it > >willfully. "Willfully" is a key word there; the parent might be > >compromised and forced to attack the child. > > I'm not sure this is true. It's entirely possible that a large enterprise I didn't say it was certainly true. As I said, I think it'd be right to default the algorithm to use only the host's domain, not any of its parents. > has a smaller core of trusted services which live in a separate realm, not > operated by the same people who operate the top-level realm, and which does > not trust the top-level realm. Think of a security group within a large > company, or a large legal or financial firm with a small group that lives > behind a Chinese wall, or a government contractor with a group that does > classified work. I could see that, which is why I hedged what I wrote ("pretty good _bet_"). > I'm nervous about making the assumption that organizational structure > implies trust relationships. It is very common to create smaller > organizational units which are either unusually trusted or unusually > distrusted compared to the rest of the organization. I'm not arguing about what the default should be. Just that there should be a way to get a host2realm() that: a) is simple, b) doesn't require KDC-side configuration of such mappings, c) doesn't require client-side configuration of them either. From ghudson at MIT.EDU Wed Oct 1 18:40:07 2008 From: ghudson at MIT.EDU (Greg Hudson) Date: Wed, 01 Oct 2008 18:40:07 -0400 Subject: Realm lookups again In-Reply-To: <20081001202803.GN1157@Sun.COM> References: <200810011944.m91Ji4fe015125@outgoing-legacy.mit.edu> <20081001202803.GN1157@Sun.COM> Message-ID: <1222900807.6796.60.camel@error-messages.mit.edu> On Wed, 2008-10-01 at 15:28 -0500, Nicolas Williams wrote: > The heuristic in the ticket does not depend on _kerberos.domain TXT RRs, > nor does it depend on DNS for the (lookup_kdcs(realm) part if DNS > lookups for KDCs are not enabled. I can't see the patch, and I don't > think this is in OpenSolaris, so I can't speak to what's in the patch. Ignore _kerberos.domain TXT RRs for the moment. There are two parts to the Sun patch: 1. Implement the heuristic for host->realm 2. Determine default_realm by applying the heuristic to the host's interface names and DNS search path. Part 1 only uses DNS if dns_lookup_kdc is true (the default), so you're correct as far as that goes. By my reading, part 2 uses DNS to reverse-resolve the host's interfaces addresses if dns_lookup_realm is *false* (also the default). If you can subvert that reverse lookup, you can make the library try to use any realm it can successfully look up as the default. > The severity of such an attack depends on whether you trust EXAMPLE.COM > not to create host-based principals for hosts in bar.example.com. Now, > with this heuristic this is a determination of trust that one would have > to make for every domain/realm. For host->realm conversion, yes. For default_realm determination, I believe there are other attacks--mainly convincing a host not to do keytab verification because it can't find a suitable service key in its keytab for the (wrong) default realm. (That particular attack goes away if, as you suggest, we use the realm from the host's keytab entries in preference to information from DNS.) From Nicolas.Williams at sun.com Wed Oct 1 18:39:13 2008 From: Nicolas.Williams at sun.com (Nicolas Williams) Date: Wed, 1 Oct 2008 17:39:13 -0500 Subject: Realm lookups again In-Reply-To: <20081001222134.GE1157@Sun.COM> References: <200810011944.m91Ji4fe015125@outgoing-legacy.mit.edu> <200810012036.m91KafBV010554@raisinbran.srv.cs.cmu.edu> <20081001222134.GE1157@Sun.COM> Message-ID: <20081001223913.GI1158@Sun.COM> On Wed, Oct 01, 2008 at 05:21:34PM -0500, Nicolas Williams wrote: > On Wed, Oct 01, 2008 at 06:14:21PM -0400, Jeffrey Hutzelman wrote: > > Think of a security group within a large > > company, or a large legal or financial firm with a small group that lives > > behind a Chinese wall, or a government contractor with a group that does > > classified work. > > I could see that, which is why I hedged what I wrote ("pretty good > _bet_"). It's also worth pointing out that creating multiple realms for chinese wall separation isn't necessarily a way to avoid having to trust an untrustworthy realm. With x-realm trusts then you still have one realm dependent on the other's security, and without x-realm trusts you end up having multiple user principals to keep synchronized, which make you wonder why bother separating them. You could have shortcut x-realm trusts between sub-realms to avoid having to trust a parent realm, but you still end up having to trust some realms (and why bother with a parent realm if it's effectively unused?). From Nicolas.Williams at sun.com Wed Oct 1 18:47:29 2008 From: Nicolas.Williams at sun.com (Nicolas Williams) Date: Wed, 1 Oct 2008 17:47:29 -0500 Subject: Realm lookups again In-Reply-To: <1222900807.6796.60.camel@error-messages.mit.edu> References: <200810011944.m91Ji4fe015125@outgoing-legacy.mit.edu> <20081001202803.GN1157@Sun.COM> <1222900807.6796.60.camel@error-messages.mit.edu> Message-ID: <20081001224728.GG1157@Sun.COM> On Wed, Oct 01, 2008 at 06:40:07PM -0400, Greg Hudson wrote: > Ignore _kerberos.domain TXT RRs for the moment. OK :) > There are two parts to the Sun patch: > > 1. Implement the heuristic for host->realm > 2. Determine default_realm by applying the heuristic to the host's > interface names and DNS search path. > > Part 1 only uses DNS if dns_lookup_kdc is true (the default), so you're > correct as far as that goes. > > By my reading, part 2 uses DNS to reverse-resolve the host's interfaces > addresses if dns_lookup_realm is *false* (also the default). If you can > subvert that reverse lookup, you can make the library try to use any > realm it can successfully look up as the default. Agreed. > > The severity of such an attack depends on whether you trust EXAMPLE.COM > > not to create host-based principals for hosts in bar.example.com. Now, > > with this heuristic this is a determination of trust that one would have > > to make for every domain/realm. > > For host->realm conversion, yes. For default_realm determination, I > believe there are other attacks--mainly convincing a host not to do > keytab verification because it can't find a suitable service key in its > keytab for the (wrong) default realm. IMO a host should never skip TGT verification for local logins. (That should be the default anyways.) (Unless the TGT is obtained via PKINIT or FAST w/ PKINIT w/ anon PKINIT client, so that the AS is explicitly authenticated to the client host.) > (That particular attack goes away if, as you suggest, we use the realm > from the host's keytab entries in preference to information from DNS.) Yes. Nico -- From hotz at jpl.nasa.gov Wed Oct 1 21:44:25 2008 From: hotz at jpl.nasa.gov (Henry B. Hotz) Date: Wed, 1 Oct 2008 18:44:25 -0700 Subject: Realm lookups again In-Reply-To: References: Message-ID: <410FC4F2-5EDA-4DEB-B767-03ED4F5CF890@jpl.nasa.gov> On Oct 1, 2008, at 3:37 PM, krbdev-request at mit.edu wrote: > Date: Wed, 01 Oct 2008 18:14:21 -0400 > From: Jeffrey Hutzelman > Subject: Re: Realm lookups again > To: Nicolas Williams , ghudson at mit.edu > Cc: krbdev at mit.edu, jhutz at cmu.edu > Message-ID: > Content-Type: text/plain; charset=us-ascii; format=flowed > > --On Wednesday, October 01, 2008 03:28:03 PM -0500 Nicolas Williams > wrote: > >> It's a pretty good bet that sub-domain/sub-realm relationships imply >> that that the child domain/realm trusts the parent not to attack it >> willfully. "Willfully" is a key word there; the parent might be >> compromised and forced to attack the child. > > I'm not sure this is true. It's entirely possible that a large > enterprise > has a smaller core of trusted services which live in a separate > realm, not > operated by the same people who operate the top-level realm, and > which does > not trust the top-level realm. Think of a security group within a > large > company, or a large legal or financial firm with a small group that > lives > behind a Chinese wall, or a government contractor with a group that > does > classified work. > > I'm nervous about making the assumption that organizational structure > implies trust relationships. It is very common to create smaller > organizational units which are either unusually trusted or unusually > distrusted compared to the rest of the organization. > > -- Jeff Aren't we running into the issue of what "trust" means? Just because you "trust" another organization enough to exchange cryptographic keys, doesn't mean you "trust" their people to access all of your services. In theory I might someday get a fully-authenticated connection from osama at AL-QAEDA.INT via some "trust" between NASA, the State Department, and a covert arm of the CIA. I've got a pretty good idea what I do with that connection too. ;-) More specifically I don't think such a connection should be regarded as an "attack", at least not by default. Rejecting it, post- authentication, is just business as usual. What we're talking about here are what are appropriate heuristics for what "trust" relationships to look for. While a security group probably doesn't want to "trust" it's parent, it makes perfect sense for the code to *look* for such a "trust". Maybe it's an outreach group, not a security group, for instance. ------------------------------------------------------ The opinions expressed in this message are mine, not those of Caltech, JPL, NASA, or the US Government. Henry.B.Hotz at jpl.nasa.gov, or hbhotz at oxy.edu From jhutz at cmu.edu Wed Oct 1 23:32:16 2008 From: jhutz at cmu.edu (Jeffrey Hutzelman) Date: Wed, 01 Oct 2008 23:32:16 -0400 Subject: Realm lookups again In-Reply-To: <200810020145.m921jP5n008268@grapenut.srv.cs.cmu.edu> References: <200810020145.m921jP5n008268@grapenut.srv.cs.cmu.edu> Message-ID: --On Wednesday, October 01, 2008 06:44:25 PM -0700 "Henry B. Hotz" wrote: > > On Oct 1, 2008, at 3:37 PM, krbdev-request at mit.edu wrote: > >> Date: Wed, 01 Oct 2008 18:14:21 -0400 >> From: Jeffrey Hutzelman >> Subject: Re: Realm lookups again >> To: Nicolas Williams , ghudson at mit.edu >> Cc: krbdev at mit.edu, jhutz at cmu.edu >> Message-ID: >> Content-Type: text/plain; charset=us-ascii; format=flowed >> >> --On Wednesday, October 01, 2008 03:28:03 PM -0500 Nicolas Williams >> wrote: >> >>> It's a pretty good bet that sub-domain/sub-realm relationships imply >>> that that the child domain/realm trusts the parent not to attack it >>> willfully. "Willfully" is a key word there; the parent might be >>> compromised and forced to attack the child. >> >> I'm not sure this is true. It's entirely possible that a large >> enterprise >> has a smaller core of trusted services which live in a separate >> realm, not >> operated by the same people who operate the top-level realm, and >> which does >> not trust the top-level realm. Think of a security group within a >> large >> company, or a large legal or financial firm with a small group that >> lives >> behind a Chinese wall, or a government contractor with a group that >> does >> classified work. >> >> I'm nervous about making the assumption that organizational structure >> implies trust relationships. It is very common to create smaller >> organizational units which are either unusually trusted or unusually >> distrusted compared to the rest of the organization. >> >> -- Jeff > > Aren't we running into the issue of what "trust" means? Just because > you "trust" another organization enough to exchange cryptographic > keys, doesn't mean you "trust" their people to access all of your > services That is true, which is why I hate the term "cross-realm trust". But no, in this case we're being very specific; Nico said "the child domain/realm trusts the parent not to attack it willfully". And one of the attacks we're talking about is the parent attempting to impersonate one of the child realm's services by causing domain-to-realm lookups to return incorrect results. It's possible that, given two heirarchically-related realms, the outer realm can be trusted not to attempt to impersonate services in the inner realm in this way. However, it's also possible that the outer realm cannot be trusted in this way, in which case assuming that it could would leave one vulnerable. It seems to me that "secure by default" demands that such an assumption not be made without explicit policy to the contrary. -- Jeff From Nicolas.Williams at sun.com Wed Oct 1 23:48:34 2008 From: Nicolas.Williams at sun.com (Nicolas Williams) Date: Wed, 1 Oct 2008 22:48:34 -0500 Subject: Realm lookups again In-Reply-To: References: <200810020145.m921jP5n008268@grapenut.srv.cs.cmu.edu> Message-ID: <20081002034834.GL1157@Sun.COM> On Wed, Oct 01, 2008 at 11:32:16PM -0400, Jeffrey Hutzelman wrote: > > Aren't we running into the issue of what "trust" means? Just because > > you "trust" another organization enough to exchange cryptographic > > keys, doesn't mean you "trust" their people to access all of your > > services Yeah, Jeff's example was a chinese wall, but if there's an x-realm trust across that wall then you don't have a chinese wall :) > That is true, which is why I hate the term "cross-realm trust". Well, sure, and then we could say that we hate the term "trusted third party." Yet that's what the KDC is in Kerberos (and the CA in PKI). > But no, in this case we're being very specific; Nico said "the child > domain/realm trusts the parent not to attack it willfully". And one of the > attacks we're talking about is the parent attempting to impersonate one of > the child realm's services by causing domain-to-realm lookups to return > incorrect results. Yes. Your example of a case where we could not assume this trusting relationship was not a very good one. A better example would be something like a service-provider relationship between the child and the parent realms. But the point is that yes, one can imagine such a situation, so it's not a good idea to default to assuming that children realms trust parent realms. > It's possible that, given two heirarchically-related realms, the outer > realm can be trusted not to attempt to impersonate services in the inner > realm in this way. However, it's also possible that the outer realm cannot > be trusted in this way, in which case assuming that it could would leave > one vulnerable. It seems to me that "secure by default" demands that such > an assumption not be made without explicit policy to the contrary. I agree. And yet, I think that this host2realm algorithm is safer than the TXT RR lookup algorithm since the attacker is far more constrained w.r.t. what realms he can redirect the client to. Also, this host2realm algorithm works with DNS lookups for KDCs disabled, provided you have a fully populated [realm] section in krb5.conf, but without having to furnish a fully populated [domain_realm] section. IOW, there's value, even much value, in this scheme. Make it default to not searching up the hierarchy unless DNS lookups are disabled, and you've got something that is secure and convenient. Nico -- From ghudson at MIT.EDU Thu Oct 2 02:35:18 2008 From: ghudson at MIT.EDU (Greg Hudson) Date: Thu, 02 Oct 2008 02:35:18 -0400 Subject: Realm lookups again In-Reply-To: <200810011944.m91Ji4fe015125@outgoing-legacy.mit.edu> References: <200810011944.m91Ji4fe015125@outgoing-legacy.mit.edu> Message-ID: <48E46BA6.6030408@mit.edu> Here is my current thinking on the patch, based on the discussion so far: 1. The default_realm part of the patch is of limited value. It's not a safe default, which means it can't (without compromising security) accomplish the goal of making Kerberos work with zero configuration. Once there is any kind of configuration requirement, people are better off configuring the default realm. 2. The host->realm part of the patch would let people throw away most of their domain_realm table. So does http://k5wiki.kerberos.org/wiki/Projects/domain_realm_referrals ; I would be interested to know what the status of that project is, and whether people think it would supplant the need for a DNS heuristic or complement it. Or if people think the DNS heuristic is a better idea than domain realm referrals. Assuming we do want the code for the DNS heuristic for host->realm mappings, it has some security implications when used in combination with dns_lookup_kdc (which is on by default), and therefore should not be turned on by default. I am open to opinions on what the configuration schema should be for enabling it; there is some room for confusion with the existing dns_lookup_realm variable. Thanks for the input so far. From Mark.Phalan at Sun.COM Thu Oct 2 05:54:03 2008 From: Mark.Phalan at Sun.COM (Mark Phalan) Date: Thu, 02 Oct 2008 11:54:03 +0200 Subject: Realm lookups again In-Reply-To: <48E46BA6.6030408@mit.edu> References: <200810011944.m91Ji4fe015125@outgoing-legacy.mit.edu> <48E46BA6.6030408@mit.edu> Message-ID: <1222941243.4356.43.camel@zup> On Thu, 2008-10-02 at 02:35 -0400, Greg Hudson wrote: > Here is my current thinking on the patch, based on the discussion so far: > > 1. The default_realm part of the patch is of limited value. It's not a > safe default, which means it can't (without compromising security) > accomplish the goal of making Kerberos work with zero configuration. > Once there is any kind of configuration requirement, people are better > off configuring the default realm. The security problem is that it does a lookup for each interface IP address. (As already mentioned by Nico) this could be replaced by looking in the keytab for host's keytab entries and using the realm found there. Alternatively the local /etc/hosts database could be used to look for the interface addresses - actually I understood that libresolv will look into /etc/hosts before going to DNS (Nico?). > > 2. The host->realm part of the patch would let people throw away most of > their domain_realm table. So does > http://k5wiki.kerberos.org/wiki/Projects/domain_realm_referrals ; I > would be interested to know what the status of that project is, and > whether people think it would supplant the need for a DNS heuristic or > complement it. Or if people think the DNS heuristic is a better idea > than domain realm referrals. I think that both are desireable. The DNS heuristic doesn't require any server-side support so will work in more situations. Referrals have advantages but do require KDC support. -M From raeburn at MIT.EDU Thu Oct 2 09:35:14 2008 From: raeburn at MIT.EDU (Ken Raeburn) Date: Thu, 2 Oct 2008 09:35:14 -0400 Subject: Realm lookups again In-Reply-To: <1222941243.4356.43.camel@zup> References: <200810011944.m91Ji4fe015125@outgoing-legacy.mit.edu> <48E46BA6.6030408@mit.edu> <1222941243.4356.43.camel@zup> Message-ID: <3DD24725-1EF2-49C7-84E7-F450AFA90886@mit.edu> On Oct 2, 2008, at 05:54, Mark Phalan wrote: > On Thu, 2008-10-02 at 02:35 -0400, Greg Hudson wrote: >> Here is my current thinking on the patch, based on the discussion >> so far: >> >> 1. The default_realm part of the patch is of limited value. It's >> not a >> safe default, which means it can't (without compromising security) >> accomplish the goal of making Kerberos work with zero configuration. >> Once there is any kind of configuration requirement, people are >> better >> off configuring the default realm. > > The security problem is that it does a lookup for each interface IP > address. > (As already mentioned by Nico) this could be replaced by looking in > the > keytab for host's keytab entries and using the realm found there. > Alternatively the local /etc/hosts database could be used to look for > the interface addresses - actually I understood that libresolv will > look > into /etc/hosts before going to DNS (Nico?). It sounds to me like there's still a risk if there's any address not listed. Like, say, an autoconfigured IPv6 address derived from a bogus router advertisement. I'm inclined to think that, when you register a machine for a service key, you're no longer in a "zero configuration" case, and the issuing realm should probably just then become the default realm, at least for the purposes of accepting and verifying credentials. It gets trickier when you could conceivably have a machine with services registered in multiple realms, a case we look at fairly rarely, and probably handle poorly already, but let's not make it any worse. >> 2. The host->realm part of the patch would let people throw away >> most of >> their domain_realm table. So does >> http://k5wiki.kerberos.org/wiki/Projects/domain_realm_referrals ; I >> would be interested to know what the status of that project is, and >> whether people think it would supplant the need for a DNS heuristic >> or >> complement it. Or if people think the DNS heuristic is a better idea >> than domain realm referrals. > > I think that both are desireable. The DNS heuristic doesn't require > any > server-side support so will work in more situations. Referrals have > advantages but do require KDC support. I think the domain_realm referrals proposal is probably in its final form, and I expect we'll eventually work on implementing it, if no one else wants to give it a shot sooner. But for realms where it's not implemented, and there's no applicable domain_realm mapping on the client, the DNS heuristic is probably a good fallback, if we're already risking DNS spoofing because of name canonicalization. Ken From Nicolas.Williams at sun.com Thu Oct 2 11:29:22 2008 From: Nicolas.Williams at sun.com (Nicolas Williams) Date: Thu, 2 Oct 2008 10:29:22 -0500 Subject: Realm lookups again In-Reply-To: <1222941243.4356.43.camel@zup> References: <200810011944.m91Ji4fe015125@outgoing-legacy.mit.edu> <48E46BA6.6030408@mit.edu> <1222941243.4356.43.camel@zup> Message-ID: <20081002152922.GT1157@Sun.COM> On Thu, Oct 02, 2008 at 11:54:03AM +0200, Mark Phalan wrote: > On Thu, 2008-10-02 at 02:35 -0400, Greg Hudson wrote: > > Here is my current thinking on the patch, based on the discussion so far: > > > > 1. The default_realm part of the patch is of limited value. It's not a > > safe default, which means it can't (without compromising security) > > accomplish the goal of making Kerberos work with zero configuration. > > Once there is any kind of configuration requirement, people are better > > off configuring the default realm. > > The security problem is that it does a lookup for each interface IP > address. > (As already mentioned by Nico) this could be replaced by looking in the > keytab for host's keytab entries and using the realm found there. Note that the keytab lookup can't be done at run-time. The process doing the lookup may not have the permission to do it. So it has to be done at realm-join time. OpenSolaris has a ralm-join facility, but MIT krb5 does not. > Alternatively the local /etc/hosts database could be used to look for > the interface addresses - actually I understood that libresolv will look > into /etc/hosts before going to DNS (Nico?). Getting host info from /etc/hosts is probably not a good idea -- the names there may not be FQDNed, and reading only from /etc/hosts may be tricky to do portably. > > 2. The host->realm part of the patch would let people throw away most of > > their domain_realm table. So does > > http://k5wiki.kerberos.org/wiki/Projects/domain_realm_referrals ; I > > would be interested to know what the status of that project is, and > > whether people think it would supplant the need for a DNS heuristic or > > complement it. Or if people think the DNS heuristic is a better idea > > than domain realm referrals. > > I think that both are desireable. The DNS heuristic doesn't require any > server-side support so will work in more situations. Referrals have > advantages but do require KDC support. Right. Nico -- From Nicolas.Williams at sun.com Thu Oct 2 11:34:30 2008 From: Nicolas.Williams at sun.com (Nicolas Williams) Date: Thu, 2 Oct 2008 10:34:30 -0500 Subject: Realm lookups again In-Reply-To: <3DD24725-1EF2-49C7-84E7-F450AFA90886@mit.edu> References: <200810011944.m91Ji4fe015125@outgoing-legacy.mit.edu> <48E46BA6.6030408@mit.edu> <1222941243.4356.43.camel@zup> <3DD24725-1EF2-49C7-84E7-F450AFA90886@mit.edu> Message-ID: <20081002153430.GU1157@Sun.COM> On Thu, Oct 02, 2008 at 09:35:14AM -0400, Ken Raeburn wrote: > I'm inclined to think that, when you register a machine for a service > key, you're no longer in a "zero configuration" case, and the issuing Good point. > realm should probably just then become the default realm, at least for > the purposes of accepting and verifying credentials. It gets trickier > when you could conceivably have a machine with services registered in > multiple realms, a case we look at fairly rarely, and probably handle > poorly already, but let's not make it any worse. But in that case the sysadmin can be expected to decide. > I think the domain_realm referrals proposal is probably in its final > form, and I expect we'll eventually work on implementing it, if no one > else wants to give it a shot sooner. But for realms where it's not > implemented, and there's no applicable domain_realm mapping on the > client, the DNS heuristic is probably a good fallback, if we're > already risking DNS spoofing because of name canonicalization. Right. And the risk with the proposed host2realm heuristic is much more constrained than the risk with the TXT RR lookup (redirect to service at PARENT vs redirect to service at REALM-OF-ATTACKER'S-CHOICE) or the lookups done by krb5_sname_to_principal() (redirect to any service at ANY-REALM). Though the fix for the krb5_sname_to_principal() issue is completely unrelated to the host2realm issue, so we shouldn't use krb5_sname_to_principal() as an excuse for whatever we choose to do for host2realm. Nico -- From Mark.Phalan at Sun.COM Thu Oct 2 11:50:44 2008 From: Mark.Phalan at Sun.COM (Mark Phalan) Date: Thu, 02 Oct 2008 17:50:44 +0200 Subject: Realm lookups again In-Reply-To: <20081002152922.GT1157@Sun.COM> References: <200810011944.m91Ji4fe015125@outgoing-legacy.mit.edu> <48E46BA6.6030408@mit.edu> <1222941243.4356.43.camel@zup> <20081002152922.GT1157@Sun.COM> Message-ID: <1222962644.4356.103.camel@zup> On Thu, 2008-10-02 at 10:29 -0500, Nicolas Williams wrote: > On Thu, Oct 02, 2008 at 11:54:03AM +0200, Mark Phalan wrote: > > On Thu, 2008-10-02 at 02:35 -0400, Greg Hudson wrote: > > > Here is my current thinking on the patch, based on the discussion so far: > > > > > > 1. The default_realm part of the patch is of limited value. It's not a > > > safe default, which means it can't (without compromising security) > > > accomplish the goal of making Kerberos work with zero configuration. > > > Once there is any kind of configuration requirement, people are better > > > off configuring the default realm. > > > > The security problem is that it does a lookup for each interface IP > > address. > > (As already mentioned by Nico) this could be replaced by looking in the > > keytab for host's keytab entries and using the realm found there. > > Note that the keytab lookup can't be done at run-time. The process > doing the lookup may not have the permission to do it. True. > > So it has to be done at realm-join time. OpenSolaris has a ralm-join > facility, but MIT krb5 does not. But only be when joining an AD realm ? > > > Alternatively the local /etc/hosts database could be used to look for > > the interface addresses - actually I understood that libresolv will look > > into /etc/hosts before going to DNS (Nico?). > > Getting host info from /etc/hosts is probably not a good idea -- the > names there may not be FQDNed, and reading only from /etc/hosts may be > tricky to do portably. Right. -M From raeburn at MIT.EDU Thu Oct 2 11:56:53 2008 From: raeburn at MIT.EDU (Ken Raeburn) Date: Thu, 2 Oct 2008 11:56:53 -0400 Subject: Realm lookups again In-Reply-To: <20081002152922.GT1157@Sun.COM> References: <200810011944.m91Ji4fe015125@outgoing-legacy.mit.edu> <48E46BA6.6030408@mit.edu> <1222941243.4356.43.camel@zup> <20081002152922.GT1157@Sun.COM> Message-ID: <3F503DD0-0F09-4F14-BBD1-CB0F01FEA559@mit.edu> On Oct 2, 2008, at 11:29, Nicolas Williams wrote: > On Thu, Oct 02, 2008 at 11:54:03AM +0200, Mark Phalan wrote: >> (As already mentioned by Nico) this could be replaced by looking in >> the >> keytab for host's keytab entries and using the realm found there. > > Note that the keytab lookup can't be done at run-time. The process > doing the lookup may not have the permission to do it. True, but such processes are not server processes, they're client processes, so the security impact would be different. The "keytab entry not found because of wrong realm name" problem can't come up. > So it has to be done at realm-join time. OpenSolaris has a ralm-join > facility, but MIT krb5 does not. Yeah, we should fix that. Want to contribute yours? :) Ken From Mark.Phalan at Sun.COM Thu Oct 2 11:59:31 2008 From: Mark.Phalan at Sun.COM (Mark Phalan) Date: Thu, 02 Oct 2008 17:59:31 +0200 Subject: pkinit: using RSA modulus to locate private key Message-ID: <1222963171.4356.113.camel@zup> One issue I ran into when working with PKINIT on OpenSolaris was that our tool for storing certs and keys in PKCS11 tokens (pkinit(1)) doesn't generate a CKA_ID for private keys - it leaves it blank. When PKINIT finds a suitable cert and then looks for a corresponding private key it fails to locate it (unless it's the only key available). I've implemented a fallback so that if PKINIT can't find a suitable key by CKA_ID it will try to find a private key matching the RSA modulus associated with its key. As the CKA_ID is typically a hash of the modulus it seemed to me to be a suitable fallback. Does this sound reasonable? I can contribute a patch. -M From Nicolas.Williams at sun.com Thu Oct 2 11:55:21 2008 From: Nicolas.Williams at sun.com (Nicolas Williams) Date: Thu, 2 Oct 2008 10:55:21 -0500 Subject: Realm lookups again In-Reply-To: <1222962644.4356.103.camel@zup> References: <200810011944.m91Ji4fe015125@outgoing-legacy.mit.edu> <48E46BA6.6030408@mit.edu> <1222941243.4356.43.camel@zup> <20081002152922.GT1157@Sun.COM> <1222962644.4356.103.camel@zup> Message-ID: <20081002155521.GA1157@Sun.COM> On Thu, Oct 02, 2008 at 05:50:44PM +0200, Mark Phalan wrote: > On Thu, 2008-10-02 at 10:29 -0500, Nicolas Williams wrote: > > So it has to be done at realm-join time. OpenSolaris has a ralm-join > > facility, but MIT krb5 does not. > > But only be when joining an AD realm ? No, when joining any realm. From Mark.Phalan at Sun.COM Thu Oct 2 12:11:22 2008 From: Mark.Phalan at Sun.COM (Mark Phalan) Date: Thu, 02 Oct 2008 18:11:22 +0200 Subject: pkinit: using RSA modulus to locate private key In-Reply-To: <1222963171.4356.113.camel@zup> References: <1222963171.4356.113.camel@zup> Message-ID: <1222963882.4356.115.camel@zup> On Thu, 2008-10-02 at 17:59 +0200, Mark Phalan wrote: > > One issue I ran into when working with PKINIT on OpenSolaris was that > our tool for storing certs and keys in PKCS11 tokens (pkinit(1)) ^^^^^^ pktool(1) -M From Nicolas.Williams at sun.com Thu Oct 2 13:08:02 2008 From: Nicolas.Williams at sun.com (Nicolas Williams) Date: Thu, 2 Oct 2008 12:08:02 -0500 Subject: Realm lookups again In-Reply-To: <3F503DD0-0F09-4F14-BBD1-CB0F01FEA559@mit.edu> References: <200810011944.m91Ji4fe015125@outgoing-legacy.mit.edu> <48E46BA6.6030408@mit.edu> <1222941243.4356.43.camel@zup> <20081002152922.GT1157@Sun.COM> <3F503DD0-0F09-4F14-BBD1-CB0F01FEA559@mit.edu> Message-ID: <20081002170802.GF1157@Sun.COM> On Thu, Oct 02, 2008 at 11:56:53AM -0400, Ken Raeburn wrote: > On Oct 2, 2008, at 11:29, Nicolas Williams wrote: > >On Thu, Oct 02, 2008 at 11:54:03AM +0200, Mark Phalan wrote: > >>(As already mentioned by Nico) this could be replaced by looking in > >>the > >>keytab for host's keytab entries and using the realm found there. > > > >Note that the keytab lookup can't be done at run-time. The process > >doing the lookup may not have the permission to do it. > > True, but such processes are not server processes, they're client > processes, so the security impact would be different. The "keytab > entry not found because of wrong realm name" problem can't come up. Server processes don't care what the default realm is. Clients, specifically AS clients, do. > >So it has to be done at realm-join time. OpenSolaris has a ralm-join > >facility, but MIT krb5 does not. > > Yeah, we should fix that. Yes, you should. > Want to contribute yours? :) I'll ask :) Ours has a lot of Solaris-specific stuff in it (e.g., PAM configuration). I'm not sure how portable it can be made. Also, it's a KSH script, not a C program. Nico -- From Nicolas.Williams at sun.com Thu Oct 2 13:38:20 2008 From: Nicolas.Williams at sun.com (Nicolas Williams) Date: Thu, 2 Oct 2008 12:38:20 -0500 Subject: Realm lookups again In-Reply-To: <48E46BA6.6030408@mit.edu> References: <200810011944.m91Ji4fe015125@outgoing-legacy.mit.edu> <48E46BA6.6030408@mit.edu> Message-ID: <20081002173820.GJ1157@Sun.COM> On Thu, Oct 02, 2008 at 02:35:18AM -0400, Greg Hudson wrote: > Assuming we do want the code for the DNS heuristic for host->realm > mappings, it has some security implications when used in combination > with dns_lookup_kdc (which is on by default), and therefore should not > be turned on by default. I am open to opinions on what the > configuration schema should be for enabling it; there is some room for > confusion with the existing dns_lookup_realm variable. One possibility: [libdefaults] host2realm_parents = Another: [libdefaults] host2realm_safe_parents = host2realm_unsafe_parents = Nico -- From Qiang.Xu at fujixerox.com Thu Oct 2 21:25:08 2008 From: Qiang.Xu at fujixerox.com (Xu, Qiang (FXSGSC)) Date: Fri, 3 Oct 2008 09:25:08 +0800 Subject: -f option with kinit Message-ID: Hi, all: To begin with, we are using krb5 MIT implementation as Kerberos client. My problem is, kinit crashes with the option -f. 1. Failure: denalic01:/tmp/dlms/kerberos/apps <138> kinit -f 120117097110 at SESSWIN2003.COM -M 070097105114049050051 Segmentation fault (core dumped) 2. Success: denalic01:/tmp/dlms/kerberos/apps <140> kinit 120117097110 at SESSWIN2003.COM -M 070097105114049050051 denalic01:/tmp/dlms/kerberos/apps <141> It seems the command line is not quite right. Anything wrong with this -f option? Looking forward to help, Xu Qiang From raeburn at MIT.EDU Thu Oct 2 22:39:50 2008 From: raeburn at MIT.EDU (Ken Raeburn) Date: Thu, 2 Oct 2008 22:39:50 -0400 Subject: -f option with kinit In-Reply-To: References: Message-ID: <6341C20C-62D5-4B67-B528-F8020BECC81B@mit.edu> On Oct 2, 2008, at 21:25, Xu, Qiang (FXSGSC) wrote: > Hi, all: > > To begin with, we are using krb5 MIT implementation as Kerberos > client. > > My problem is, kinit crashes with the option -f. > > 1. Failure: > denalic01:/tmp/dlms/kerberos/apps <138> kinit -f 120117097110 at SESSWIN2003.COM > -M 070097105114049050051 > Segmentation fault (core dumped) > > 2. Success: > denalic01:/tmp/dlms/kerberos/apps <140> kinit 120117097110 at SESSWIN2003.COM > -M 070097105114049050051 > denalic01:/tmp/dlms/kerberos/apps <141> > > It seems the command line is not quite right. Anything wrong with > this -f option? There shouldn't be; it just sets a flag in the request. What's the -M option? A stack trace from the core dump may help indicate what's wrong. Ken From Qiang.Xu at fujixerox.com Thu Oct 2 23:17:17 2008 From: Qiang.Xu at fujixerox.com (Xu, Qiang (FXSGSC)) Date: Fri, 3 Oct 2008 11:17:17 +0800 Subject: -f option with kinit In-Reply-To: <6341C20C-62D5-4B67-B528-F8020BECC81B@mit.edu> References: <6341C20C-62D5-4B67-B528-F8020BECC81B@mit.edu> Message-ID: > -----Original Message----- > From: Ken Raeburn [mailto:raeburn at MIT.EDU] > Sent: Friday, October 03, 2008 10:40 AM > To: Xu, Qiang (FXSGSC) > Cc: krbdev at mit.edu > Subject: Re: -f option with kinit > > There shouldn't be; it just sets a flag in the request. Agree, I am also confused by this behavior. > What's the -M option? This -M option is a Xerox modification for the password flag, indicating the username needs to be converted to UTF-8 encoding (but no conversion of password, as per what you have instructed me last year). By default, the option should be -X. > A stack trace from the core dump may help indicate what's wrong. Just as you said. Previously I didn't find where the core file lies. Now I have managed to locate it. And GDB shows the stack trace is: ========================================================================= Core was generated by `./kinit -f 120117097110 at SESSWIN2003.COM -M 070097105114049050051'. Program terminated with signal 11, Segmentation fault. #0 0x42d04829 in strcat () from /lib/libc.so.6 (gdb) bt #0 0x42d04829 in strcat () from /lib/libc.so.6 #1 0x0804ad47 in parse_options (argc=5, argv=0xbf8301a0, opts=0xbf8301a0, progname=0xbf831457 "kinit") at kinit.c:659 #2 0x0804b5f6 in main (argc=5, argv=0xbf830284) at kinit.c:1458 (gdb) ========================================================================= Fortunately, this falls in the part of Xerox modification (#ifdef XEROX_MODIFICATIONS_KERBEROS). So I think I can fix the defect of the modifcation later. Thank you, Xu Qiang From Qiang.Xu at fujixerox.com Fri Oct 3 02:04:35 2008 From: Qiang.Xu at fujixerox.com (Xu, Qiang (FXSGSC)) Date: Fri, 3 Oct 2008 14:04:35 +0800 Subject: -f option with kinit In-Reply-To: <6341C20C-62D5-4B67-B528-F8020BECC81B@mit.edu> References: <6341C20C-62D5-4B67-B528-F8020BECC81B@mit.edu> Message-ID: > -----Original Message----- > From: Ken Raeburn [mailto:raeburn at MIT.EDU] > Sent: Friday, October 03, 2008 10:40 AM > To: Xu, Qiang (FXSGSC) > Cc: krbdev at mit.edu > Subject: Re: -f option with kinit > > A stack trace from the core dump may help indicate what's wrong. Just as you said, the stack trace reveals some useful information, and I have fixed that to avoid the crash. :-) My next question is, the authenticaion with "-f" option (forwardable) seems successful. But how can I determine that there is a forwarding ticket or not? The network trace captured in the process only shows the request is "Forwardable", the return packet is of type "KRB5KRB_AP_ERR_SKEW". In the code for kinit, Xerox Modification just ignores this skew error, and takes it for success. Apart from this, there is no more packet from the server. In my case, I want to know whether there is a forwarding ticket, and further, I want to obtain that ticket. Does that mean I must overcome this skew error first? Thanks, Xu Qiang From mike.patnode at centrify.com Fri Oct 3 12:14:11 2008 From: mike.patnode at centrify.com (Mike Patnode) Date: Fri, 3 Oct 2008 09:14:11 -0700 Subject: telnet & ftp official status In-Reply-To: <1222891292.6796.47.camel@error-messages.mit.edu> References: <20080918000446.GA5266@sun.com> <73708652-DDDB-4402-B058-69B5156D121F@mit.edu> <20080919151016.GC1875@Sun.COM><3917C005-FA40-41DF-828D-026E9139E481@kth.se> <200809191608.m8JG87D7021184@raisinbran.srv.cs.cmu.edu> <20080919210411.GD1875@Sun.COM> <8763od9w6i.fsf@windlord.stanford.edu> <1222891292.6796.47.camel@error-messages.mit.edu> Message-ID: >> The question is do you want the diffs for >> the Coverity & Valgrind issues against the 1.4.3 base, or do you just >> want to wait until we do our 1.6 port? >If the goal is to save effort on our end by avoiding duplicate work, >then we'll want patches against the most recent Kerberos source >code--ideally the trunk. >Also, it's easiest to review patches when they are logically separated. >I don't want 200 separate patches for 200 defects, but if they could be >collected into categories (like "eliminate memory leaks") it will make >my life easier. The thought was we could leverage the investment we've already made with Coverity to save you some time, unfortunately, we don't have the resources to go back and repackage the changes in this manner. >Based on a piece of mail from Tom in July, I believe our recommended >method for delivering patches from non-commiters is to send mail to >krb5-bugs at mit.edu to create a ticket in RT, including patches in >attachments. Sounds like the easiest strategy will be to start creating bugs for our changes moving forward as we make them. Potentially we'll have time for a stronger push for integration sometime next year and we'll sync with something closer to your trunk. >Finally, if in any of your analysis you uncovered evidence of an >exploitable security issue, we'd like to hear about it in (ideally >PGP-encrypted) email to krbcore-security at mit.edu. My experience is that >most Coverity-discovered defects are not security issues, but there may >be a few hidden in there. The double free's were mostly discovered by valgrind testing. It's not clear if those our issues outside of our usage scenario, but as they come up again, we'll be sure to open bugs. mp From Nicolas.Williams at sun.com Fri Oct 3 11:55:35 2008 From: Nicolas.Williams at sun.com (Nicolas Williams) Date: Fri, 3 Oct 2008 10:55:35 -0500 Subject: -f option with kinit In-Reply-To: References: <6341C20C-62D5-4B67-B528-F8020BECC81B@mit.edu> Message-ID: <20081003155535.GL1157@Sun.COM> On Fri, Oct 03, 2008 at 02:04:35PM +0800, Xu, Qiang (FXSGSC) wrote: > My next question is, the authenticaion with "-f" option (forwardable) > seems successful. But how can I determine that there is a forwarding > ticket or not? klist -f will tell you if the ticket you got was forwardable. From ghudson at MIT.EDU Fri Oct 3 16:43:38 2008 From: ghudson at MIT.EDU (Greg Hudson) Date: Fri, 03 Oct 2008 16:43:38 -0400 Subject: telnet & ftp official status In-Reply-To: References: <20080918000446.GA5266@sun.com> <73708652-DDDB-4402-B058-69B5156D121F@mit.edu> <20080919151016.GC1875@Sun.COM> <3917C005-FA40-41DF-828D-026E9139E481@kth.se> <200809191608.m8JG87D7021184@raisinbran.srv.cs.cmu.edu> <20080919210411.GD1875@Sun.COM> <8763od9w6i.fsf@windlord.stanford.edu> <1222891292.6796.47.camel@error-messages.mit.edu> Message-ID: <1223066618.6796.65.camel@error-messages.mit.edu> On Fri, 2008-10-03 at 09:14 -0700, Mike Patnode wrote: > The thought was we could leverage the investment we've already made with > Coverity to save you some time, unfortunately, we don't have the > resources to go back and repackage the changes in this manner. How about this: send us the changes you have against 1.4.3, and when we're going over the defects we uncover ourselves with Coverity, we'll consult your changes to see what you did about them. That should save some time. (And if possible, we'll look over anything in your changes which doesn't show up under Coverity for us, but that may turn out to be impractical due to version skew.) From Nicolas.Williams at sun.com Fri Oct 3 17:22:32 2008 From: Nicolas.Williams at sun.com (Nicolas Williams) Date: Fri, 3 Oct 2008 16:22:32 -0500 Subject: telnet & ftp official status In-Reply-To: <1222891292.6796.47.camel@error-messages.mit.edu> References: <20080919151016.GC1875@Sun.COM> <3917C005-FA40-41DF-828D-026E9139E481@kth.se> <200809191608.m8JG87D7021184@raisinbran.srv.cs.cmu.edu> <20080919210411.GD1875@Sun.COM> <8763od9w6i.fsf@windlord.stanford.edu> <1222891292.6796.47.camel@error-messages.mit.edu> Message-ID: <20081003212232.GP1157@Sun.COM> On Wed, Oct 01, 2008 at 04:01:32PM -0400, Greg Hudson wrote: > We discussed this process a bit yesterday. It's okay to informally > discuss an API or feature change on the list before you've assembled the > complete project proposal with detailed design and API documentation and > so on. That way if it turns out we're not interested in a change, you > haven't gone through the whole rigamarole for nothing. > > There downside is if the discussion peters out or rejects the proposal, > there is no discoverable artifact left behind, only a thread in the > mailing list archive which will quickly get lost. When I get a bit more > settled, I will think about how best to record information about > "non-projects" so that they can be referred to later, either using RT or > the wiki. This is an excellent point/idea. Nico -- From Nicolas.Williams at sun.com Fri Oct 3 17:29:54 2008 From: Nicolas.Williams at sun.com (Nicolas Williams) Date: Fri, 3 Oct 2008 16:29:54 -0500 Subject: telnet & ftp official status In-Reply-To: References: <20080918000446.GA5266@sun.com> <73708652-DDDB-4402-B058-69B5156D121F@mit.edu> <20080919151016.GC1875@Sun.COM> <3917C005-FA40-41DF-828D-026E9139E481@kth.se> <200809191608.m8JG87D7021184@raisinbran.srv.cs.cmu.edu> <20080919210411.GD1875@Sun.COM> Message-ID: <20081003212954.GQ1157@Sun.COM> On Tue, Sep 30, 2008 at 12:00:37PM -0400, Tom Yu wrote: > A few questions we need to consider are: > > * Who needs these applications, and why? Not OpenSolaris :) > * What should be done about the protocol vulnerabilities? Well, if you distribute the apps, whether directly or indirectly, then you should fix them. Better to drop the apps :) > * What advantages are there compared to SSH? FTP may perform better than many SFTP/SSHv2 implementations; I'm not sure. Other than that I can't think what advantages the MIT krb5 apps offer over SSHv2. I don't think such an advantage should be considered significant -- let the SSHv2 implementors improve their implementations' performance if that's needed. > * Should we continue bundling the applications? I recomment against it. Spin them off into a separate repository and invite others to maintain them. HOWEVER, that's *my* *personal* advice/ opinion. It is not Sun's opinion as a consortium member, and other members might strongly oppose such a move. > The continued presence of these applications in the MIT Kerberos > source tree raises a number of issues. These applications, by virtue > of being login-related applications, present a multitude of > portability challenges. Operating system interfaces related to user > login activities appear to have the some of the largest variations of > any operating system interfaces. > > Additionally, having the release cycle of these applications tied to > that of the core MIT Kerberos source code is problematic. Security > vulnerabilities discovered in the applications will require an update > to the krb5 package, due to bundling. For vendors wishing to track > only the core Kerberos libraries and utilities, this can create > difficulties with their change management processes. This argues for, at the very least, separating the apps from the core. Nico -- From kenh at cmf.nrl.navy.mil Fri Oct 3 20:40:19 2008 From: kenh at cmf.nrl.navy.mil (Ken Hornstein) Date: Fri, 03 Oct 2008 20:40:19 -0400 Subject: telnet & ftp official status In-Reply-To: <20081003212954.GQ1157@Sun.COM> Message-ID: <200810040041.m940fcGM021637@ginger.cmf.nrl.navy.mil> >FTP may perform better than many SFTP/SSHv2 implementations; I'm not >sure. Other than that I can't think what advantages the MIT krb5 apps >offer over SSHv2. I don't think such an advantage should be considered >significant -- let the SSHv2 implementors improve their implementations' >performance if that's needed. The two big advantages that come to mind for me are: - The code and protocols are simpler (Well, okay, telnet is the exception here). That makes modification and maintenance easier. - They actually _return all the damn Kerberos errors_. In OpenSSH ... well, you can run it in some super-debugging mode and get client-side errors, if you want to spent your time sorting through piles of crap. Server-side errors are not returned to the client in most cases (rumor is that they are logged on the server somewhere, but inevitably that's on some machine that I am not an administrator on). The Kerberos integration in OpenSSH just plain bites on a practical level. Perhaps it is better in other SSH implementations, but I have no experience with them. (Getting back to FTP ... it is out-of-the-box faster, assuming encryption is not on of course, and it is easy to make it perform very fast). Just FYI, I have no problem with the apps being split off to another tree, or run by someone else (*cough* Russ *cough*). --Ken From simon at sxw.org.uk Sat Oct 4 09:22:54 2008 From: simon at sxw.org.uk (Simon Wilkinson) Date: Sat, 4 Oct 2008 14:22:54 +0100 Subject: telnet & ftp official status In-Reply-To: <200810040041.m940fcGM021637@ginger.cmf.nrl.navy.mil> References: <200810040041.m940fcGM021637@ginger.cmf.nrl.navy.mil> Message-ID: On 4 Oct 2008, at 01:40, Ken Hornstein wrote: > Perhaps it is better in > other SSH implementations, but I have no experience with them. This is an implementation, rather than a protocol, deficiency. There is support in the protocol for returning the text of Kerberos errors to the client. OpenSSH doesn't do so, because it was felt to add unnecessary complexity at the point the code was being integrated. No- one has had the energy to revist this since (I have the code, it's just not in their tree). Cheers, Simon. From ghudson at MIT.EDU Sat Oct 4 10:36:46 2008 From: ghudson at MIT.EDU (Greg Hudson) Date: Sat, 04 Oct 2008 10:36:46 -0400 Subject: Realm lookups again In-Reply-To: <48E46BA6.6030408@mit.edu> References: <200810011944.m91Ji4fe015125@outgoing-legacy.mit.edu> <48E46BA6.6030408@mit.edu> Message-ID: <1223131006.6796.84.camel@error-messages.mit.edu> Thanks for the input so far. One final (I hope) question about the host->realm heuristic: domain = fqdn; while (domain.label_count > 2) { domain = pop_label(domain); realm = domain2realm(domain); /* for ASCII: toupper() */ if (lookup_kdcs(realm) > 0) break; realm = NULL; } Is there any reason not to check the domain itself as a realm? For example, if you are doing Kerberized HTTP authentication to sun.com, would you not want the client to intuit that the appropriate realm of sun.com is SUN.COM? (I reviewed the Dec 2006 and April 2008 threads about this topic, and found no direct discussion of this specific point.) From jaltman at secure-endpoints.com Sat Oct 4 10:56:51 2008 From: jaltman at secure-endpoints.com (Jeffrey Altman) Date: Sat, 04 Oct 2008 10:56:51 -0400 Subject: Realm lookups again In-Reply-To: <1223131006.6796.84.camel@error-messages.mit.edu> References: <200810011944.m91Ji4fe015125@outgoing-legacy.mit.edu> <48E46BA6.6030408@mit.edu> <1223131006.6796.84.camel@error-messages.mit.edu> Message-ID: <48E78433.7040502@secure-endpoints.com> Greg Hudson wrote: > Thanks for the input so far. One final (I hope) question about the > host->realm heuristic: > > domain = fqdn; > while (domain.label_count > 2) { > domain = pop_label(domain); > realm = domain2realm(domain); /* for ASCII: toupper() */ > if (lookup_kdcs(realm) > 0) > break; > realm = NULL; > } > > Is there any reason not to check the domain itself as a realm? For > example, if you are doing Kerberized HTTP authentication to sun.com, > would you not want the client to intuit that the appropriate realm of > sun.com is SUN.COM? > > (I reviewed the Dec 2006 and April 2008 threads about this topic, and > found no direct discussion of this specific point.) I believe the answer is 'yes'. Jeffrey Altman -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/x-pkcs7-signature Size: 3355 bytes Desc: S/MIME Cryptographic Signature Url : http://mailman.mit.edu/pipermail/krbdev/attachments/20081004/cd36c198/smime-0001.bin From jhutz at cmu.edu Sat Oct 4 12:16:10 2008 From: jhutz at cmu.edu (Jeffrey Hutzelman) Date: Sat, 04 Oct 2008 12:16:10 -0400 Subject: telnet & ftp official status In-Reply-To: <200810041324.m94DOKot002453@raisinbran.srv.cs.cmu.edu> References: <200810040041.m940fcGM021637@ginger.cmf.nrl.navy.mil> <200810041324.m94DOKot002453@raisinbran.srv.cs.cmu.edu> Message-ID: <89BC66AEF464898213A7752B@atlantis.pc.cs.cmu.edu> --On Saturday, October 04, 2008 02:22:54 PM +0100 Simon Wilkinson wrote: > > On 4 Oct 2008, at 01:40, Ken Hornstein wrote: >> Perhaps it is better in >> other SSH implementations, but I have no experience with them. > > This is an implementation, rather than a protocol, deficiency. Funny; that's what I was going to say. This _wasn't_ in the protocol initially, but was added as a result of a specific request to be able to do this. Unfortunately, IMHO we weren't strong enough about it; we said the server MAY send this information instead of specifying that it SHOULD. Sadly, I don't think it would help much. What the protocol actually carries is a GSS major and minor status and a text message. A server implementation which does not have intimate details about the underlying GSS-API mechanism implementation can't do much better than to call GSS_Display_status, which returns exactly those values. Unfortunately, it is all too common for the returned error to be KRB5KRB_ERR_GENERIC, with the real error being buried in a Kerberos protocol field that never gets extracted. -- Jeff From raeburn at MIT.EDU Sat Oct 4 13:04:41 2008 From: raeburn at MIT.EDU (Ken Raeburn) Date: Sat, 4 Oct 2008 13:04:41 -0400 Subject: telnet & ftp official status In-Reply-To: <89BC66AEF464898213A7752B@atlantis.pc.cs.cmu.edu> References: <200810040041.m940fcGM021637@ginger.cmf.nrl.navy.mil> <200810041324.m94DOKot002453@raisinbran.srv.cs.cmu.edu> <89BC66AEF464898213A7752B@atlantis.pc.cs.cmu.edu> Message-ID: <406F71F3-B1AA-4F43-B37C-1F37123B4E68@mit.edu> On Oct 4, 2008, at 12:16, Jeffrey Hutzelman wrote: > Sadly, I don't think it would help much. What the protocol actually > carries is a GSS major and minor status and a text message. A server Since the minor status values are mechanism- and implementation- specific (and in MIT's current code, could theoretically be allocated at run time in certain cases), transferring them from the server is kind of useless. The text message may be useful, though. > implementation which does not have intimate details about the > underlying > GSS-API mechanism implementation can't do much better than to call > GSS_Display_status, which returns exactly those values. > Unfortunately, it > is all too common for the returned error to be KRB5KRB_ERR_GENERIC, > with > the real error being buried in a Kerberos protocol field that never > gets > extracted. That's an implementation issue we Kerberos implementors can try to do something about... and the MIT implementation should be better in that regard than it used to be, with the new krb5_get_error_message interface, which the GSSAPI code should be using. Ken From jhutz at cmu.edu Sat Oct 4 13:11:34 2008 From: jhutz at cmu.edu (Jeffrey Hutzelman) Date: Sat, 04 Oct 2008 13:11:34 -0400 Subject: telnet & ftp official status In-Reply-To: <200810041704.m94H4omW025378@toasties.srv.cs.cmu.edu> References: <200810040041.m940fcGM021637@ginger.cmf.nrl.navy.mil> <200810041324.m94DOKot002453@raisinbran.srv.cs.cmu.edu> <89BC66AEF464898213A7752B@atlantis.pc.cs.cmu.edu> <200810041704.m94H4omW025378@toasties.srv.cs.cmu.edu> Message-ID: <2ECBCA4EDE0169DA9E003BCD@atlantis.pc.cs.cmu.edu> --On Saturday, October 04, 2008 01:04:41 PM -0400 Ken Raeburn wrote: > On Oct 4, 2008, at 12:16, Jeffrey Hutzelman wrote: >> Sadly, I don't think it would help much. What the protocol actually >> carries is a GSS major and minor status and a text message. A server > > Since the minor status values are mechanism- and implementation-specific > (and in MIT's current code, could theoretically be allocated at run time > in certain cases), transferring them from the server is kind of useless. > The text message may be useful, though. They're only useless to client implementors, because they don't know what they're talking to. In real deployments using this mechanism, it will often be the case that the user knows what they're talking or, or their sysadmin does, or their help desk has a list of codes and what to do about them, prepared by someone who knows. Or at least, that'd be the case if this were ever used. FWIW, I thought the minor_status values were implementation-dependent, too, but RFC2743 only calls them mechanism-specific. So at a minimum, I think it is possible to have mechanisms which specify their meaning, even though the Kerberos V mechanism does not do so. -- Jeff From raeburn at MIT.EDU Sat Oct 4 13:35:04 2008 From: raeburn at MIT.EDU (Ken Raeburn) Date: Sat, 4 Oct 2008 13:35:04 -0400 Subject: telnet & ftp official status In-Reply-To: <2ECBCA4EDE0169DA9E003BCD@atlantis.pc.cs.cmu.edu> References: <200810040041.m940fcGM021637@ginger.cmf.nrl.navy.mil> <200810041324.m94DOKot002453@raisinbran.srv.cs.cmu.edu> <89BC66AEF464898213A7752B@atlantis.pc.cs.cmu.edu> <200810041704.m94H4omW025378@toasties.srv.cs.cmu.edu> <2ECBCA4EDE0169DA9E003BCD@atlantis.pc.cs.cmu.edu> Message-ID: On Oct 4, 2008, at 13:11, Jeffrey Hutzelman wrote: > FWIW, I thought the minor_status values were implementation- > dependent, too, but RFC2743 only calls them mechanism-specific. So > at a minimum, I think it is possible to have mechanisms which > specify their meaning, even though the Kerberos V mechanism does not > do so. RFC 2743 section 1.2.8 calls them "locally-significant", which suggests that across systems they needn't have the same values. RFC 2744 variously calls them mechanism-specific or implementation- specific. It's difficult or impossible to determine which mechanism returned a given error in certain cases; in some calls, the minor status is supposedly mechanism-specific, but there's clearly no specific mechanism involved. See gss_indicate_mechs and gss_create_empty_oid_set, for example. Other mechanism specs I've looked at also do not specify minor status values, although at least one specified the top bit or two for different classes of mechanism-specific errors, and left them otherwise unspecified. And the general recommendation is that an implementation should provide "a facility" to translate the symbolic names to the values used by the implementation; it's not even required to be C macros expanding to integer constants. Calling functions with these symbols as string arguments, or macros expanding to function calls, would be acceptable. (At least, I don't think the C bindings make it more specific.) Ken From kenh at cmf.nrl.navy.mil Sat Oct 4 20:24:58 2008 From: kenh at cmf.nrl.navy.mil (Ken Hornstein) Date: Sat, 04 Oct 2008 20:24:58 -0400 Subject: telnet & ftp official status In-Reply-To: <89BC66AEF464898213A7752B@atlantis.pc.cs.cmu.edu> Message-ID: <200810050026.m950QKPM002930@ginger.cmf.nrl.navy.mil> >Sadly, I don't think it would help much. What the protocol actually >carries is a GSS major and minor status and a text message. A server >implementation which does not have intimate details about the underlying >GSS-API mechanism implementation can't do much better than to call >GSS_Display_status, which returns exactly those values. Unfortunately, it >is all too common for the returned error to be KRB5KRB_ERR_GENERIC, with >the real error being buried in a Kerberos protocol field that never gets >extracted. Actually, that's not been my experience. With the MIT Kerberos gssftp implementation gss_display_status on the minor error code always ends up displaying the "real" Kerberos error message, and I don't think I've ever seen gssftp spit out KRB5KRB_ERR_GENERIC. It's certainly useful enough that it's always helped in debugging problems. Admittedly OpenSSH isn't the only GSS-API program that likes to hide the real error message (*cough* kadmin *cough*) but it's certainly possible to return something useful. --Ken From Qiang.Xu at fujixerox.com Sun Oct 5 21:32:07 2008 From: Qiang.Xu at fujixerox.com (Xu, Qiang (FXSGSC)) Date: Mon, 6 Oct 2008 09:32:07 +0800 Subject: -f option with kinit In-Reply-To: <20081003155535.GL1157@Sun.COM> References: <6341C20C-62D5-4B67-B528-F8020BECC81B@mit.edu> <20081003155535.GL1157@Sun.COM> Message-ID: > -----Original Message----- > From: Nicolas Williams [mailto:Nicolas.Williams at sun.com] > Sent: Friday, October 03, 2008 11:56 PM > To: Xu, Qiang (FXSGSC) > Cc: Ken Raeburn; krbdev at mit.edu > Subject: Re: -f option with kinit > > klist -f will tell you if the ticket you got was forwardable. Here is my command sequence and the response: denalic01:/tmp/dlms/kerberos/apps <78> kinit 120117097110 at SESSWIN2003.COM -M 070097105114049050051 denalic01:/tmp/dlms/kerberos/apps <79> klist -f klist: No credentials cache found (ticket cache FILE:/tmp/krb5cc_0) denalic01:/tmp/dlms/kerberos/apps <80> kinit 120117097110 at SESSWIN2003.COM -M 070097105114049050051 -f denalic01:/tmp/dlms/kerberos/apps <81> klist -f klist: No credentials cache found (ticket cache FILE:/tmp/krb5cc_0) Since on two occasions, klist -f returns the same result, it seems there is no ticket, is there? Thanks, Xu Qiang From Nicolas.Williams at sun.com Sun Oct 5 22:18:53 2008 From: Nicolas.Williams at sun.com (Nicolas Williams) Date: Sun, 5 Oct 2008 21:18:53 -0500 Subject: -f option with kinit In-Reply-To: References: <6341C20C-62D5-4B67-B528-F8020BECC81B@mit.edu> <20081003155535.GL1157@Sun.COM> Message-ID: <20081006021853.GQ1157@Sun.COM> On Mon, Oct 06, 2008 at 09:32:07AM +0800, Xu, Qiang (FXSGSC) wrote: > > -----Original Message----- > > From: Nicolas Williams [mailto:Nicolas.Williams at sun.com] > > Sent: Friday, October 03, 2008 11:56 PM > > To: Xu, Qiang (FXSGSC) > > Cc: Ken Raeburn; krbdev at mit.edu > > Subject: Re: -f option with kinit > > > > klist -f will tell you if the ticket you got was forwardable. > > Here is my command sequence and the response: > > denalic01:/tmp/dlms/kerberos/apps <78> kinit 120117097110 at SESSWIN2003.COM -M 070097105114049050051 > denalic01:/tmp/dlms/kerberos/apps <79> klist -f > klist: No credentials cache found (ticket cache FILE:/tmp/krb5cc_0) > denalic01:/tmp/dlms/kerberos/apps <80> kinit 120117097110 at SESSWIN2003.COM -M 070097105114049050051 -f > denalic01:/tmp/dlms/kerberos/apps <81> klist -f > klist: No credentials cache found (ticket cache FILE:/tmp/krb5cc_0) > > Since on two occasions, klist -f returns the same result, it seems there is no ticket, is there? Yup. You'll need to spend more time debugging your kinit changes :) From tlyu at MIT.EDU Mon Oct 6 12:07:37 2008 From: tlyu at MIT.EDU (Tom Yu) Date: Mon, 06 Oct 2008 12:07:37 -0400 Subject: pkinit: using RSA modulus to locate private key In-Reply-To: <1222963171.4356.113.camel@zup> (Mark Phalan's message of "Thu, 02 Oct 2008 17:59:31 +0200") References: <1222963171.4356.113.camel@zup> Message-ID: Mark Phalan writes: > One issue I ran into when working with PKINIT on OpenSolaris was that > our tool for storing certs and keys in PKCS11 tokens (pkinit(1)) doesn't > generate a CKA_ID for private keys - it leaves it blank. When PKINIT > finds a suitable cert and then looks for a corresponding private key it > fails to locate it (unless it's the only key available). I've > implemented a fallback so that if PKINIT can't find a suitable key by > CKA_ID it will try to find a private key matching the RSA modulus > associated with its key. As the CKA_ID is typically a hash of the > modulus it seemed to me to be a suitable fallback. > > Does this sound reasonable? I can contribute a patch. Is there a CKA_ID on the certificate? Also, my reading of PKCS11 is that the CKA_ID is not required to match the subjectKeyIdentifier, but this may not be a significant problem. Your approach sounds reasonable, but I first would like else someone more familiar with PKCS11 than I am to provide feedback. From Mark.Phalan at Sun.COM Mon Oct 6 12:27:18 2008 From: Mark.Phalan at Sun.COM (Mark Phalan) Date: Mon, 06 Oct 2008 18:27:18 +0200 Subject: pkinit: using RSA modulus to locate private key In-Reply-To: References: <1222963171.4356.113.camel@zup> Message-ID: <1223310438.28336.32.camel@zup> On Mon, 2008-10-06 at 12:07 -0400, Tom Yu wrote: > Mark Phalan writes: > > > One issue I ran into when working with PKINIT on OpenSolaris was that > > our tool for storing certs and keys in PKCS11 tokens (pkinit(1)) doesn't > > generate a CKA_ID for private keys - it leaves it blank. When PKINIT > > finds a suitable cert and then looks for a corresponding private key it > > fails to locate it (unless it's the only key available). I've > > implemented a fallback so that if PKINIT can't find a suitable key by > > CKA_ID it will try to find a private key matching the RSA modulus > > associated with its key. As the CKA_ID is typically a hash of the > > modulus it seemed to me to be a suitable fallback. > > > > Does this sound reasonable? I can contribute a patch. > > Is there a CKA_ID on the certificate? When stored with pktool(1) certificates have a CKA_ID stored along with them. > Also, my reading of PKCS11 is > that the CKA_ID is not required to match the subjectKeyIdentifier, but > this may not be a significant problem. > > Your approach sounds reasonable, but I first would like else someone > more familiar with PKCS11 than I am to provide feedback. Ok. I'd also like to hear someone with PKCS11 experience give their opinion on this. -M From deengert at anl.gov Mon Oct 6 16:10:10 2008 From: deengert at anl.gov (Douglas E. Engert) Date: Mon, 06 Oct 2008 15:10:10 -0500 Subject: pkinit: using RSA modulus to locate private key In-Reply-To: References: <1222963171.4356.113.camel@zup> Message-ID: <48EA70A2.1000900@anl.gov> Tom Yu wrote: > Mark Phalan writes: > >> One issue I ran into when working with PKINIT on OpenSolaris was that >> our tool for storing certs and keys in PKCS11 tokens (pkinit(1)) doesn't >> generate a CKA_ID for private keys - it leaves it blank. Can you change your pkinit utility? But since many tokens don't store the CKA_ID then what? >> When PKINIT >> finds a suitable cert and then looks for a corresponding private key it >> fails to locate it (unless it's the only key available). I've >> implemented a fallback so that if PKINIT can't find a suitable key by >> CKA_ID it will try to find a private key matching the RSA modulus >> associated with its key. Assuming you are using RSA key, that might work. PKCS#11 2.20 says 12.1.3: "The only attributes from Table 36 for which a Cryptoki implementation is required to be able to return values are CKA_MODULUS and CKA_PRIVATE_EXPONENT" But there might be cards where this is not true, as the card may not store this information. >> As the CKA_ID is typically a hash of the >> modulus it seemed to me to be a suitable fallback. I don't believe that setting CK_ID to the hash is typical. OpenSC can present a PKCS#11 view of many cards, it will typically use 1, 2, 3... for the CK_ID and keep the same CK_ID for the cert, public key and matching private key, assuming that a CK_ID is unique only across a card. Note that if the MIT x509_identity with cert_id= is defined in the krb5.conf or pam_krb5 it will be in effect a constant,and thus each card used must use the same CKA_ID, for the "authentication" cert/key. >> >> Does this sound reasonable? I can contribute a patch. Yes it does. I believe the Heimdal code already does something like this. > > Is there a CKA_ID on the certificate? Also, my reading of PKCS11 is > that the CKA_ID is not required to match the subjectKeyIdentifier, but > this may not be a significant problem. > > Your approach sounds reasonable, but I first would like else someone > more familiar with PKCS11 than I am to provide feedback. > _______________________________________________ > krbdev mailing list krbdev at mit.edu > https://mailman.mit.edu/mailman/listinfo/krbdev > > -- Douglas E. Engert Argonne National Laboratory 9700 South Cass Avenue Argonne, Illinois 60439 (630) 252-5444 From raeburn at MIT.EDU Mon Oct 6 18:50:00 2008 From: raeburn at MIT.EDU (Ken Raeburn) Date: Mon, 6 Oct 2008 18:50:00 -0400 Subject: Update to the design of the Master Key Migration project In-Reply-To: <20080925212312.GF22993@sun.com> References: <20080924005955.GC22993@sun.com> <20080924204333.GD22993@sun.com> <200809242123.m8OLNZGL025980@raisinbran.srv.cs.cmu.edu> <9189F5E2145344B960DF6746@sirius.fac.cs.cmu.edu> <20080925212312.GF22993@sun.com> Message-ID: I'd like to see one (or more) test cases added -- something to verify that the various means of setting a new key (kpasswd, kadmin commands like cpw or xst, as well as the new/modified commands) when applied to the master key principal will either be rejected without changing the database or retain all the old keys, even if that list is larger than the normal key history size. That is, make sure the normal key history mechanisms won't accidentally throw away some of our still- used master keys. Ken From Mark.Phalan at Sun.COM Tue Oct 7 08:16:41 2008 From: Mark.Phalan at Sun.COM (Mark Phalan) Date: Tue, 07 Oct 2008 14:16:41 +0200 Subject: pkinit: using RSA modulus to locate private key In-Reply-To: <48EA70A2.1000900@anl.gov> References: <1222963171.4356.113.camel@zup> <48EA70A2.1000900@anl.gov> Message-ID: <1223381801.28336.70.camel@zup> On Mon, 2008-10-06 at 15:10 -0500, Douglas E. Engert wrote: > > Tom Yu wrote: > > Mark Phalan writes: > > > >> One issue I ran into when working with PKINIT on OpenSolaris was that > >> our tool for storing certs and keys in PKCS11 tokens (pkinit(1)) doesn't > >> generate a CKA_ID for private keys - it leaves it blank. > > Can you change your pkinit utility? Yes, I've filed a bug against pktool(1). http://bugs.opensolaris.org/view_bug.do?bug_id=6744761 I've no idea when the KMF team will fix it though. > But since many tokens don't store > the CKA_ID then what? Not sure I totally understand the question. If there is no CKA_ID set and the RSA modulus from a cert matches a key in the token then, with the proposed patch, that key can be used. > > >> When PKINIT > >> finds a suitable cert and then looks for a corresponding private key it > >> fails to locate it (unless it's the only key available). I've > >> implemented a fallback so that if PKINIT can't find a suitable key by > >> CKA_ID it will try to find a private key matching the RSA modulus > >> associated with its key. > > Assuming you are using RSA key, that might work. Currently PKINIT only looks for RSA keys. > PKCS#11 2.20 says 12.1.3: > "The only attributes from Table 36 for which a Cryptoki implementation > is required to be able to return values are CKA_MODULUS and > CKA_PRIVATE_EXPONENT" > > But there might be cards where this is not true, as the card may not > store this information. The proposed RSA modulus fallback is only used when a key cannot be found using the current methods. If the CKA_MODULUS is not stored then I guess the fallback will also fail. > > >> As the CKA_ID is typically a hash of the > >> modulus it seemed to me to be a suitable fallback. > > I don't believe that setting CK_ID to the hash is typical. > OpenSC can present a PKCS#11 view of many cards, it will > typically use 1, 2, 3... for the CK_ID and keep the same CK_ID > for the cert, public key and matching private key, > assuming that a CK_ID is unique only across a card. > > Note that if the MIT x509_identity with cert_id= is > defined in the krb5.conf or pam_krb5 it will be in effect a > constant,and thus each card used must use the same CKA_ID, > for the "authentication" cert/key. Right, I was wondering about the utility of that setting in krb5.conf. However if it can be easily set manually or is "well-known" (as in your example above for OpenSC) then it makes more sense. > > >> > >> Does this sound reasonable? I can contribute a patch. > > Yes it does. I believe the Heimdal code already does something > like this. The patch is pretty trivial, I'll open a ticket soon. -M From since at opendemand.com Tue Oct 7 18:49:52 2008 From: since at opendemand.com (Stephen Ince) Date: Tue, 7 Oct 2008 18:49:52 -0400 Subject: pkinit: using RSA modulus to locate private key References: <1222963171.4356.113.camel@zup> <48EA70A2.1000900@anl.gov> <1223381801.28336.70.camel@zup> Message-ID: <3bf901c928cf$03113350$6e00a8c0@desktop2> Hi, I am very new to kerberos. I am trying to connect to ad kdc server and I am getting the following error. KRB5_KDCREP_MODIFIED - KDC reply did not match expectations. The call is the following. err = krb5_get_in_tkt_with_password( krb5->context, kdcFlags, NULL, NULL, NULL, password, krb5->ccache, &krb5->credentials, 0); I am missing some additional setup. I have this call working when I use a kfw kerberos server. Basically I am doing the following. krb5_init_context(.. krb5_parse_name(. krb5_build_principal_ext(.. krb5_cc_resolve(.. krb5_cc_initialize(.. krb5_get_in_tkt_with_password(.. Steve From since at opendemand.com Tue Oct 7 21:46:20 2008 From: since at opendemand.com (Stephen Ince) Date: Tue, 7 Oct 2008 21:46:20 -0400 Subject: KRB5_KDCREP_MODIFIED - KDC reply did not match expectations error References: <1222963171.4356.113.camel@zup><48EA70A2.1000900@anl.gov> <1223381801.28336.70.camel@zup> <3bf901c928cf$03113350$6e00a8c0@desktop2> Message-ID: <3c0801c928e7$a9968460$6e00a8c0@desktop2> Hi, I am very new to kerberos. I am trying to connect to ad kdc server and I am getting the following error. KRB5_KDCREP_MODIFIED - KDC reply did not match expectations. The call is the following. err = krb5_get_in_tkt_with_password( krb5->context, kdcFlags, NULL, NULL, NULL, password, krb5->ccache, &krb5->credentials, 0); I am missing some additional setup. I have this call working when I use a kfw kerberos server. Basically I am doing the following. krb5_init_context(.. krb5_parse_name(. krb5_build_principal_ext(.. krb5_cc_resolve(.. krb5_cc_initialize(.. krb5_get_in_tkt_with_password(.. Steve From raeburn at MIT.EDU Tue Oct 7 21:59:06 2008 From: raeburn at MIT.EDU (Ken Raeburn) Date: Tue, 7 Oct 2008 21:59:06 -0400 Subject: PKINIT encoder/decoder issues Message-ID: <09CC29A8-2169-4317-B2BF-385E5612C87C@mit.edu> I'm doing a bit of work on the ASN.1 encoder routines in the MIT Kerberos library, and in preparation for that am trying to make sure that more of the encoders and decoders are actually tested under "make check". The mechanism we have for other (base protocol) types tested in src/tests/asn.1 is pretty straightforward: * We create a sample data structure, encode it, and compare the result (in hex) against saved copies. * We create a sample data structure, encode it, and feed the result through a little ASN.1 pretty-printer, and compare the result against saved copies. * We take a string with a sequence of hex values (stored separately from the above -- that's probably a bug), convert it to binary, feed it to the decoder to get a data structure, create our sample data structure, and recursively compare the two. These tests check for self-consistency and that our encodings don't change. Checking whether the expected and actual results are *correct* is a separate matter, obviously. Extra tests are sometimes run for sequences with optional fields, or cases where we want to support some non-distinguished encoding variants. There are currently no tests for the PKINIT types; I've been working on writing some. However, I see a few possible problems: In krb5_pk_authenticator_draft9, kdcRealm is set in the client-side plugin code but never used in the encoder or decoder. (So obviously initializing and comparing the field doesn't work.) It's a reference to the realm data stored in the kdcName field, and looks to me like it could just go away. In krb5_pa_pk_as_req_draft9, we encode the optional field encryptionCert with a tag of 3, but when decoding, it looks like we want it to be 2, duplicating the tag on kdcCert. In the trusted_ca encoding, with the principalName choice, the decoder is complaining about an incorrect tag value; I think it may be out of sync. The ANY DEFINED BY seems to confuse our pretty-printer. I'm not sure what to do about that except skip those tests when pretty-printing. Is there something we can stuff in that field that won't confuse it too much? Could someone more knowledgeable than I about the ASN.1 encodings and the innards of PKINIT please take a look at this? I can make my preliminary test cases available if it would help. Ken From Qiang.Xu at fujixerox.com Wed Oct 8 03:18:28 2008 From: Qiang.Xu at fujixerox.com (Xu, Qiang (FXSGSC)) Date: Wed, 8 Oct 2008 15:18:28 +0800 Subject: -f option with kinit In-Reply-To: <20081006021853.GQ1157@Sun.COM> References: <6341C20C-62D5-4B67-B528-F8020BECC81B@mit.edu> <20081003155535.GL1157@Sun.COM> <20081006021853.GQ1157@Sun.COM> Message-ID: Hi, all: Just want to know if there is any way to avoid the error of KRB5KRB_AP_ERR_SKEW? It seems a time synchronization problem. Must I enable NTP to make the time in accordance with the counter part in Kerberos server? Thanks, Xu Qiang From raeburn at MIT.EDU Wed Oct 8 08:46:45 2008 From: raeburn at MIT.EDU (Ken Raeburn) Date: Wed, 8 Oct 2008 08:46:45 -0400 Subject: -f option with kinit In-Reply-To: References: <6341C20C-62D5-4B67-B528-F8020BECC81B@mit.edu> <20081003155535.GL1157@Sun.COM> <20081006021853.GQ1157@Sun.COM> Message-ID: <7EC747C3-5429-4C83-BDE1-ABBF73776083@mit.edu> On Oct 8, 2008, at 03:18, Xu, Qiang (FXSGSC) wrote: > Just want to know if there is any way to avoid the error of > KRB5KRB_AP_ERR_SKEW? It seems a time synchronization problem. Must I > enable NTP to make the time in accordance with the counter part in > Kerberos server? The KDC will send this back if your client uses a preauth scheme which carries as part of its protocol a timestamp; you could change the client not to use these preauth schemes I suppose. Or alter the KDC either not to implement the check, or to allow a much larger maximum clock skew. From kwc at umich.edu Wed Oct 8 09:51:01 2008 From: kwc at umich.edu (Kevin Coffman) Date: Wed, 8 Oct 2008 09:51:01 -0400 Subject: PKINIT encoder/decoder issues In-Reply-To: <09CC29A8-2169-4317-B2BF-385E5612C87C@mit.edu> References: <09CC29A8-2169-4317-B2BF-385E5612C87C@mit.edu> Message-ID: <4d569c330810080651h1524d3ffk7f9ae3829d8aac55@mail.gmail.com> On Tue, Oct 7, 2008 at 9:59 PM, Ken Raeburn wrote: > I'm doing a bit of work on the ASN.1 encoder routines in the MIT > Kerberos library, and in preparation for that am trying to make sure > that more of the encoders and decoders are actually tested under "make > check". The mechanism we have for other (base protocol) types tested > in src/tests/asn.1 is pretty straightforward: > > * We create a sample data structure, encode it, and compare the result > (in hex) against saved copies. > > * We create a sample data structure, encode it, and feed the result > through a little ASN.1 pretty-printer, and compare the result against > saved copies. > > * We take a string with a sequence of hex values (stored separately > from the above -- that's probably a bug), convert it to binary, feed > it to the decoder to get a data structure, create our sample data > structure, and recursively compare the two. > > These tests check for self-consistency and that our encodings don't > change. Checking whether the expected and actual results are > *correct* is a separate matter, obviously. > > Extra tests are sometimes run for sequences with optional fields, or > cases where we want to support some non-distinguished encoding variants. > > There are currently no tests for the PKINIT types; I've been working > on writing some. However, I see a few possible problems: > > In krb5_pk_authenticator_draft9, kdcRealm is set in the client-side > plugin code but never used in the encoder or decoder. (So obviously > initializing and comparing the field doesn't work.) It's a reference > to the realm data stored in the kdcName field, and looks to me like it > could just go away. Yes. I think there was some confusion. The kdcRealm field is redundant and unused. > In krb5_pa_pk_as_req_draft9, we encode the optional field > encryptionCert with a tag of 3, but when decoding, it looks like we > want it to be 2, duplicating the tag on kdcCert. > > In the trusted_ca encoding, with the principalName choice, the decoder > is complaining about an incorrect tag value; I think it may be out of > sync. According to the draft9 definition of PA-PK-AS-REQ, kdcCert should be tag 2 and encryptionCert should be tag 3. My initial reaction is that this is a typo/bug in asn1_decode_pa_pk_as_req_draft9(). Unfortunately, I can't easily recreate the test environment to verify that. > The ANY DEFINED BY seems to confuse our pretty-printer. I'm not sure > what to do about that except skip those tests when pretty-printing. > Is there something we can stuff in that field that won't confuse it > too much? We used dumpasn1 (http://www.cs.auckland.ac.nz/~pgut001/dumpasn1.c) to look at ASN.1 structure. Maybe there is something in that code that would help the pretty-printer? > Could someone more knowledgeable than I about the ASN.1 encodings and > the innards of PKINIT please take a look at this? I can make my > preliminary test cases available if it would help. > > Ken From jhutz at cmu.edu Wed Oct 8 11:47:26 2008 From: jhutz at cmu.edu (Jeffrey Hutzelman) Date: Wed, 08 Oct 2008 11:47:26 -0400 Subject: -f option with kinit In-Reply-To: <200810081247.m98Cl9cD008280@grapenut.srv.cs.cmu.edu> References: <6341C20C-62D5-4B67-B528-F8020BECC81B@mit.edu> <20081003155535.GL1157@Sun.COM> <20081006021853.GQ1157@Sun.COM> <200810081247.m98Cl9cD008280@grapenut.srv.cs.cmu.edu> Message-ID: <4E5F755550566D371A268B23@minbar.fac.cs.cmu.edu> --On Wednesday, October 08, 2008 08:46:45 AM -0400 Ken Raeburn wrote: > On Oct 8, 2008, at 03:18, Xu, Qiang (FXSGSC) wrote: >> Just want to know if there is any way to avoid the error of >> KRB5KRB_AP_ERR_SKEW? It seems a time synchronization problem. Must I >> enable NTP to make the time in accordance with the counter part in >> Kerberos server? > > The KDC will send this back if your client uses a preauth scheme which > carries as part of its protocol a timestamp; you could change the > client not to use these preauth schemes I suppose. He could, though I'm not sure we have a good alternative at the moment. > Or alter the KDC > either not to implement the check, or to allow a much larger maximum > clock skew. I'd avoid doing this. The time check is there for a reason; if you're going to disable it you may as well not use preauth at all. A better option than either of these, if you can do it, is to just make sure your clients actually have correct time to begin with. Running an NTP client on every machine is a good way to accomplish this. -- Jeff From tsitkova at MIT.EDU Wed Oct 8 11:56:01 2008 From: tsitkova at MIT.EDU (tsitkova) Date: Wed, 8 Oct 2008 11:56:01 -0400 Subject: pkinit: using RSA modulus to locate private key In-Reply-To: <1223381801.28336.70.camel@zup> References: <1222963171.4356.113.camel@zup> <48EA70A2.1000900@anl.gov> <1223381801.28336.70.camel@zup> Message-ID: On Oct 7, 2008, at 8:16 AM, Mark Phalan wrote: > On Mon, 2008-10-06 at 15:10 -0500, Douglas E. Engert wrote: >> >> Tom Yu wrote: >>> Mark Phalan writes: >>> >>>> One issue I ran into when working with PKINIT on OpenSolaris was >>>> that >>>> our tool for storing certs and keys in PKCS11 tokens (pkinit(1)) >>>> doesn't >>>> generate a CKA_ID for private keys - it leaves it blank. >> >> Can you change your pkinit utility? > > Yes, I've filed a bug against pktool(1). > http://bugs.opensolaris.org/view_bug.do?bug_id=6744761 > I've no idea when the KMF team will fix it though. According to PKCS11 X509 the certs and the associated key pairs must have the same CKA_ID. > > >> But since many tokens don't store >> the CKA_ID then what? > > Not sure I totally understand the question. If there is no CKA_ID set > and the RSA modulus from a cert matches a key in the token then, with > the proposed patch, that key can be used. > >> >>>> When PKINIT >>>> finds a suitable cert and then looks for a corresponding private >>>> key it >>>> fails to locate it (unless it's the only key available). I've >>>> implemented a fallback so that if PKINIT can't find a suitable >>>> key by >>>> CKA_ID it will try to find a private key matching the RSA modulus >>>> associated with its key. >> >> Assuming you are using RSA key, that might work. > > Currently PKINIT only looks for RSA keys. > >> PKCS#11 2.20 says 12.1.3: >> "The only attributes from Table 36 for which a Cryptoki >> implementation >> is required to be able to return values are CKA_MODULUS and >> CKA_PRIVATE_EXPONENT" >> >> But there might be cards where this is not true, as the card may not >> store this information. > > The proposed RSA modulus fallback is only used when a key cannot be > found using the current methods. If the CKA_MODULUS is not stored > then I > guess the fallback will also fail. > >> >>>> As the CKA_ID is typically a hash of the >>>> modulus it seemed to me to be a suitable fallback. >> >> I don't believe that setting CK_ID to the hash is typical. >> OpenSC can present a PKCS#11 view of many cards, it will >> typically use 1, 2, 3... for the CK_ID and keep the same CK_ID >> for the cert, public key and matching private key, >> assuming that a CK_ID is unique only across a card. >> CKA_ID may be generated in the numerous ways. It may be a modulus of RSA, a public value of DSA, SHA1/MD5 hash of the RSA modulus or any other unique to the token identifier that maps the cert to the associated key pair. Keeping this in mind, as a work around, it might be sufficient just to extract RSA pub keys both from the cert and the priv key and compare their modulus, rather than cert's CKA_ID and the hash value of the modulus of the key pair. >> Note that if the MIT x509_identity with cert_id= is >> defined in the krb5.conf or pam_krb5 it will be in effect a >> constant,and thus each card used must use the same CKA_ID, >> for the "authentication" cert/key. > > Right, I was wondering about the utility of that setting in krb5.conf. > However if it can be easily set manually or is "well-known" (as in > your > example above for OpenSC) then it makes more sense. > >> >>>> >>>> Does this sound reasonable? I can contribute a patch. >> >> Yes it does. I believe the Heimdal code already does something >> like this. > > The patch is pretty trivial, I'll open a ticket soon. > > -M > > _______________________________________________ > krbdev mailing list krbdev at mit.edu > https://mailman.mit.edu/mailman/listinfo/krbdev Zhanna Tsitkova tsitkova at mit.edu Kerberos Consortium From Mark.Phalan at Sun.COM Wed Oct 8 12:17:03 2008 From: Mark.Phalan at Sun.COM (Mark Phalan) Date: Wed, 08 Oct 2008 18:17:03 +0200 Subject: pkinit: using RSA modulus to locate private key In-Reply-To: References: <1222963171.4356.113.camel@zup> <48EA70A2.1000900@anl.gov> <1223381801.28336.70.camel@zup> Message-ID: <1223482623.28336.164.camel@zup> On Wed, 2008-10-08 at 11:56 -0400, tsitkova wrote: > On Oct 7, 2008, at 8:16 AM, Mark Phalan wrote: > > > On Mon, 2008-10-06 at 15:10 -0500, Douglas E. Engert wrote: > >> > >> Tom Yu wrote: > >>> Mark Phalan writes: > >>> > >>>> One issue I ran into when working with PKINIT on OpenSolaris was > >>>> that > >>>> our tool for storing certs and keys in PKCS11 tokens (pkinit(1)) > >>>> doesn't > >>>> generate a CKA_ID for private keys - it leaves it blank. > >> > >> Can you change your pkinit utility? > > > > Yes, I've filed a bug against pktool(1). > > http://bugs.opensolaris.org/view_bug.do?bug_id=6744761 > > I've no idea when the KMF team will fix it though. > > According to PKCS11 X509 the certs and the associated key pairs must > have the same CKA_ID. I don't see any such statement in PKCS #11 v2.20. In fact the following is found in section 10.6.3: "It is intended in the interests of interoperability that the subject name and key identifier for a certificate will be the same as those for the corresponding public and private keys (though it is not required that all be stored in the same token). However, Cryptoki does not enforce this association, or even the uniqueness of the key identifier for a given subject; in particular, an application may leave the key identifier empty." > > > > > > >> But since many tokens don't store > >> the CKA_ID then what? > > > > Not sure I totally understand the question. If there is no CKA_ID set > > and the RSA modulus from a cert matches a key in the token then, with > > the proposed patch, that key can be used. > > > >> > >>>> When PKINIT > >>>> finds a suitable cert and then looks for a corresponding private > >>>> key it > >>>> fails to locate it (unless it's the only key available). I've > >>>> implemented a fallback so that if PKINIT can't find a suitable > >>>> key by > >>>> CKA_ID it will try to find a private key matching the RSA modulus > >>>> associated with its key. > >> > >> Assuming you are using RSA key, that might work. > > > > Currently PKINIT only looks for RSA keys. > > > >> PKCS#11 2.20 says 12.1.3: > >> "The only attributes from Table 36 for which a Cryptoki > >> implementation > >> is required to be able to return values are CKA_MODULUS and > >> CKA_PRIVATE_EXPONENT" > >> > >> But there might be cards where this is not true, as the card may not > >> store this information. > > > > The proposed RSA modulus fallback is only used when a key cannot be > > found using the current methods. If the CKA_MODULUS is not stored > > then I > > guess the fallback will also fail. > > > >> > >>>> As the CKA_ID is typically a hash of the > >>>> modulus it seemed to me to be a suitable fallback. > >> > >> I don't believe that setting CK_ID to the hash is typical. > >> OpenSC can present a PKCS#11 view of many cards, it will > >> typically use 1, 2, 3... for the CK_ID and keep the same CK_ID > >> for the cert, public key and matching private key, > >> assuming that a CK_ID is unique only across a card. > >> > > CKA_ID may be generated in the numerous ways. It may be a modulus of > RSA, a public value of DSA, SHA1/MD5 hash of the RSA modulus or any > other unique to the token identifier that maps the cert to the > associated key pair. > Keeping this in mind, as a work around, it might be sufficient just to > extract RSA pub keys both from the cert and the priv key and compare > their modulus, rather than cert's CKA_ID and the hash value of the > modulus of the key pair. Indeed thats essentially what I'm proposing (except I'm asking PKCS11 to do the comparison for me rather than doing it myself). -M From hotz at jpl.nasa.gov Wed Oct 8 15:56:57 2008 From: hotz at jpl.nasa.gov (Henry B. Hotz) Date: Wed, 8 Oct 2008 12:56:57 -0700 Subject: KRB5_KDCREP_MODIFIED - KDC reply did not match expectations error In-Reply-To: References: Message-ID: <6474B1F6-CEFE-4DC1-B2CE-9F4295DF19A4@jpl.nasa.gov> On Oct 8, 2008, at 8:56 AM, krbdev-request at mit.edu wrote: > Date: Tue, 7 Oct 2008 21:46:20 -0400 > From: "Stephen Ince" > Subject: KRB5_KDCREP_MODIFIED - KDC reply did not match expectations > error > To: "krbdev" > Message-ID: <3c0801c928e7$a9968460$6e00a8c0 at desktop2> > Content-Type: text/plain; format=flowed; charset="iso-8859-1"; > reply-type=original > > Hi, I am very new to kerberos. I am trying to connect to ad kdc > server and I > am getting the following error. > > KRB5_KDCREP_MODIFIED - KDC reply did not match expectations. > > The call is the following. > > err = krb5_get_in_tkt_with_password( > krb5->context, > kdcFlags, NULL, NULL, NULL, password, krb5->ccache, > &krb5->credentials, 0); > > I am missing some additional setup. I have this call working when I > use a > kfw kerberos server. Basically I am doing the following. > > krb5_init_context(.. > krb5_parse_name(. > krb5_build_principal_ext(.. > krb5_cc_resolve(.. > krb5_cc_initialize(.. > krb5_get_in_tkt_with_password(.. > > Steve There seem to be two ways this error can happen "in the wild". 1) if you are using a Microsoft KDC and the case of the requested principal differs from what's in the server's database. (I've not seen this myself.) 2) if you have a Heimdal KDC, the request has the renewable_ok flag set, and the time limits are set to allow extension of the renewable time limit as that flag suggests. I've seen the latter with the Sun pam_krb5 module. The MIT code doesn't generally produce requests matching case 2). IIRC the relevant code is in src/lib/krb5/krb/get_in_tkt.c, and 1.6.1b1 does not appear to have been fixed. ------------------------------------------------------ The opinions expressed in this message are mine, not those of Caltech, JPL, NASA, or the US Government. Henry.B.Hotz at jpl.nasa.gov, or hbhotz at oxy.edu From since at opendemand.com Wed Oct 8 17:19:45 2008 From: since at opendemand.com (Stephen Ince) Date: Wed, 8 Oct 2008 17:19:45 -0400 Subject: KRB5_KDCREP_MODIFIED - KDC reply did not match expectations error References: <6474B1F6-CEFE-4DC1-B2CE-9F4295DF19A4@jpl.nasa.gov> Message-ID: <425201c9298b$96a37ee0$6e00a8c0@desktop2> Henry, Thx for the tip. Steve ----- Original Message ----- From: "Henry B. Hotz" To: Cc: Sent: Wednesday, October 08, 2008 3:56 PM Subject: Re: KRB5_KDCREP_MODIFIED - KDC reply did not match expectations error > > On Oct 8, 2008, at 8:56 AM, krbdev-request at mit.edu wrote: > >> Date: Tue, 7 Oct 2008 21:46:20 -0400 >> From: "Stephen Ince" >> Subject: KRB5_KDCREP_MODIFIED - KDC reply did not match expectations >> error >> To: "krbdev" >> Message-ID: <3c0801c928e7$a9968460$6e00a8c0 at desktop2> >> Content-Type: text/plain; format=flowed; charset="iso-8859-1"; >> reply-type=original >> >> Hi, I am very new to kerberos. I am trying to connect to ad kdc server >> and I >> am getting the following error. >> >> KRB5_KDCREP_MODIFIED - KDC reply did not match expectations. >> >> The call is the following. >> >> err = krb5_get_in_tkt_with_password( >> krb5->context, >> kdcFlags, NULL, NULL, NULL, password, krb5->ccache, >> &krb5->credentials, 0); >> >> I am missing some additional setup. I have this call working when I use >> a >> kfw kerberos server. Basically I am doing the following. >> >> krb5_init_context(.. >> krb5_parse_name(. >> krb5_build_principal_ext(.. >> krb5_cc_resolve(.. >> krb5_cc_initialize(.. >> krb5_get_in_tkt_with_password(.. >> >> Steve > > > There seem to be two ways this error can happen "in the wild". 1) if you > are using a Microsoft KDC and the case of the requested principal differs > from what's in the server's database. (I've not seen this myself.) 2) > if you have a Heimdal KDC, the request has the renewable_ok flag set, and > the time limits are set to allow extension of the renewable time limit as > that flag suggests. > > I've seen the latter with the Sun pam_krb5 module. The MIT code doesn't > generally produce requests matching case 2). IIRC the relevant code is > in src/lib/krb5/krb/get_in_tkt.c, and 1.6.1b1 does not appear to have > been fixed. > > > ------------------------------------------------------ > The opinions expressed in this message are mine, > not those of Caltech, JPL, NASA, or the US Government. > Henry.B.Hotz at jpl.nasa.gov, or hbhotz at oxy.edu > > > > From tlyu at MIT.EDU Wed Oct 8 17:51:49 2008 From: tlyu at MIT.EDU (Tom Yu) Date: Wed, 08 Oct 2008 17:51:49 -0400 Subject: pkinit: using RSA modulus to locate private key In-Reply-To: <1223482623.28336.164.camel@zup> (Mark Phalan's message of "Wed, 08 Oct 2008 18:17:03 +0200") References: <1222963171.4356.113.camel@zup> <48EA70A2.1000900@anl.gov> <1223381801.28336.70.camel@zup> <1223482623.28336.164.camel@zup> Message-ID: Mark Phalan writes: > On Wed, 2008-10-08 at 11:56 -0400, tsitkova wrote: >> On Oct 7, 2008, at 8:16 AM, Mark Phalan wrote: >> CKA_ID may be generated in the numerous ways. It may be a modulus of >> RSA, a public value of DSA, SHA1/MD5 hash of the RSA modulus or any >> other unique to the token identifier that maps the cert to the >> associated key pair. >> Keeping this in mind, as a work around, it might be sufficient just to >> extract RSA pub keys both from the cert and the priv key and compare >> their modulus, rather than cert's CKA_ID and the hash value of the >> modulus of the key pair. > Indeed thats essentially what I'm proposing (except I'm asking PKCS11 to > do the comparison for me rather than doing it myself). I went back to your original message and realize now that I read some unintended meaning into it. I think now that you meant to propose the following: If lookup of certificate's private key by CKA_ID fails, extract the modulus from the certificate (or use its CKA_MODULUS?) and use that to locate the private key by CKA_MODULUS. You do not propose to directly interpret CKA_ID as a specific hash of the modulus in this fallback situation. Is this what you meant? If so, I agree with the approach and would be pleased to see a patch. I am interested in hearing about how to generalize this approach to non-RSA keys, if that actually becomes necessary. Is it possible to generalize this fallback approach without encoding knowledge specific to the public key mechanism? From tlyu at MIT.EDU Wed Oct 8 18:44:27 2008 From: tlyu at MIT.EDU (Tom Yu) Date: Wed, 08 Oct 2008 18:44:27 -0400 Subject: policy on supported platforms Message-ID: I have created a K5Wiki page documenting our policy on supported platforms for MIT Kerberos. You may find it at: http://k5wiki.kerberos.org/wiki/Supported_platforms We have informally talked about the concept of supported platforms in the past; this article attempts to formally set some expectations based on historical practice. Please note the section on "Extent of support", which defines the expectations we are establishing. Feedback on this policy is welcome. -- Tom Yu Development Manager MIT Kerberos Consortium From rra at stanford.edu Wed Oct 8 19:24:42 2008 From: rra at stanford.edu (Russ Allbery) Date: Wed, 08 Oct 2008 16:24:42 -0700 Subject: policy on supported platforms In-Reply-To: (Tom Yu's message of "Wed\, 08 Oct 2008 18\:44\:27 -0400") References: Message-ID: <87hc7m1xhh.fsf@windlord.stanford.edu> Tom Yu writes: > I have created a K5Wiki page documenting our policy on supported > platforms for MIT Kerberos. You may find it at: > > http://k5wiki.kerberos.org/wiki/Supported_platforms > > We have informally talked about the concept of supported platforms in > the past; this article attempts to formally set some expectations > based on historical practice. Please note the section on "Extent of > support", which defines the expectations we are establishing. It's a little ambiguous whether when you say you support Linux, you mean all Linux architectures or only the ones listed in parentheses afterwards. None of the parenthesized platform lists specifically mention x86_64, which is probably an oversight. Debian currently auto-builds all packages on the following architectures: alpha amd64 arm armel hppa i386 ia64 m68k mips mipsel powerpc s390 sparc although arm and m68k are on their way out as first-class platforms. I expect that few MIT Kerberos features will be sensitive to the architecture difference given that the same glibc and compilers are used uniformly. If there are any such sensitivities, it would be good to iron them out, not at the level of a first-class supported platform but maybe something a bit better than "a platform-specific problem reported on an unsupported platform will get preemptively closed unless accompanied by a very well-written patch that poses negligible integration cost for us." But generally we can provide help from the Debian side on detailed error messages and debugging, and I doubt this will be much of an issue in practice. Other than that, it seems quite sane to me. -- Russ Allbery (rra at stanford.edu) From Mark.Phalan at Sun.COM Thu Oct 9 05:52:40 2008 From: Mark.Phalan at Sun.COM (Mark Phalan) Date: Thu, 09 Oct 2008 11:52:40 +0200 Subject: pkinit: using RSA modulus to locate private key In-Reply-To: References: <1222963171.4356.113.camel@zup> <48EA70A2.1000900@anl.gov> <1223381801.28336.70.camel@zup> <1223482623.28336.164.camel@zup> Message-ID: <1223545961.28336.167.camel@zup> On Wed, 2008-10-08 at 17:51 -0400, Tom Yu wrote: > Mark Phalan writes: > > > On Wed, 2008-10-08 at 11:56 -0400, tsitkova wrote: > >> On Oct 7, 2008, at 8:16 AM, Mark Phalan wrote: > > >> CKA_ID may be generated in the numerous ways. It may be a modulus of > >> RSA, a public value of DSA, SHA1/MD5 hash of the RSA modulus or any > >> other unique to the token identifier that maps the cert to the > >> associated key pair. > >> Keeping this in mind, as a work around, it might be sufficient just to > >> extract RSA pub keys both from the cert and the priv key and compare > >> their modulus, rather than cert's CKA_ID and the hash value of the > >> modulus of the key pair. > > > Indeed thats essentially what I'm proposing (except I'm asking PKCS11 to > > do the comparison for me rather than doing it myself). > > I went back to your original message and realize now that I read some > unintended meaning into it. I think now that you meant to propose the > following: > > If lookup of certificate's private key by CKA_ID fails, extract the > modulus from the certificate (or use its CKA_MODULUS?) and use that to > locate the private key by CKA_MODULUS. Exactly. Sorry if I wasn't clear in my mail. > > You do not propose to directly interpret CKA_ID as a specific hash of > the modulus in this fallback situation. Nope. > > Is this what you meant? If so, I agree with the approach and would be > pleased to see a patch. Great. > > I am interested in hearing about how to generalize this approach to > non-RSA keys, if that actually becomes necessary. Is it possible to > generalize this fallback approach without encoding knowledge specific > to the public key mechanism? Thats not something I've thought about. I'm open to suggestions. -M From Qiang.Xu at fujixerox.com Thu Oct 9 22:47:09 2008 From: Qiang.Xu at fujixerox.com (Xu, Qiang (FXSGSC)) Date: Fri, 10 Oct 2008 10:47:09 +0800 Subject: -f option with kinit In-Reply-To: <7EC747C3-5429-4C83-BDE1-ABBF73776083@mit.edu> References: <6341C20C-62D5-4B67-B528-F8020BECC81B@mit.edu> <20081003155535.GL1157@Sun.COM> <20081006021853.GQ1157@Sun.COM> <7EC747C3-5429-4C83-BDE1-ABBF73776083@mit.edu> Message-ID: > -----Original Message----- > From: Ken Raeburn [mailto:raeburn at MIT.EDU] > Sent: Wednesday, October 08, 2008 8:47 PM > To: Xu, Qiang (FXSGSC) > Cc: Nicolas Williams; krbdev at mit.edu > Subject: Re: -f option with kinit > > The KDC will send this back if your client uses a preauth > scheme which carries as part of its protocol a timestamp; you > could change the client not to use these preauth schemes I > suppose. Or alter the KDC either not to implement the check, > or to allow a much larger maximum clock skew. Based on your suggestions and Jeffery's opinion, I have taken a shortcut, that is, to manually set the printer's time and gmtoffset to be the same as those in KDC. And this can eliminate the time sync error KRB5KRB_AP_ERR_SKEW. That saves me the hassle and tussle with NTP for now. :-) And now, I can have the tickets: =================================================== denalic01:/tmp/dlms/kerberos/apps <201> kinit 120117097110 at SESSWIN2003.COM -M 070097105114049050051 denalic01:/tmp/dlms/kerberos/apps <202> klist -f Ticket cache: FILE:/tmp/krb5cc_0 Default principal: xuan at SESSWIN2003.COM Valid starting Expires Service principal 10/10/08 11:09:24 10/10/08 21:09:35 krbtgt/SESSWIN2003.COM at SESSWIN2003.COM renew until 10/11/08 11:09:24, Flags: RIA denalic01:/tmp/dlms/kerberos/apps <203> kinit 120117097110 at SESSWIN2003.COM -M 070097105114049050051 -f denalic01:/tmp/dlms/kerberos/apps <204> klist -f Ticket cache: FILE:/tmp/krb5cc_0 Default principal: xuan at SESSWIN2003.COM Valid starting Expires Service principal 10/10/08 11:11:00 10/10/08 21:11:11 krbtgt/SESSWIN2003.COM at SESSWIN2003.COM renew until 10/11/08 11:11:00, Flags: FRIA =================================================== It seems I can get the tickets from the server whether or not the request is forwardable. The only difference seems in the flags returned, with FRIA for forwardable request, and RIA for non-forwardable request. Does the character F in the flags FRIA represent "forwardable"? Just want to confirm what I get the server is correct. Thanks, Xu Qiang From ghudson at MIT.EDU Tue Oct 14 21:06:26 2008 From: ghudson at MIT.EDU (ghudson@MIT.EDU) Date: Tue, 14 Oct 2008 21:06:26 -0400 (EDT) Subject: "Secure coding" audit checkers and Kerberos Message-ID: <200810150106.m9F16QC1004443@outgoing-legacy.mit.edu> We've been asked to stop using "traditionally insecure" functions (like strcpy) in order to make krb5 code conform to the standards of code bases which incorporate it. I'm developing coding standards in line with this goal. For the moment, I'm working from Coverity's "secure coding" checker, which is flagging the use of the following functions in the code base: sprintf strcpy/strcat sscanf/fscanf random/lrand48/rand If there are other functions flagged by Solaris lint or similar tools, please let me know. I would prefer not to recommend truncating functions as alternatives in most cases. Silent truncation can sometimes result in bugs or security holes which cannot be detected by static analysis tools. Here are my initial ideas, as a starting point for discussion: * Instead of strcpy or strcat, use memcpy. Remember to ensure that the string is terminated if you are not copying a terminator. * Instead of using sprintf to convert an integral type into a string, use snprintf with an 80-byte buffer. * Instead of using sprintf to compose a human-readable string (such as an error message), use snprintf or asprintf. * Instead of using sprintf to compose a pathname or other internal string, use asprintf or manual composition. asprintf will require a check for allocation failure. * Instead of using sprintf to compose a human-readable message, use snprintf. * Instead of using sscanf or fscanf, use manual parsing; use strtol or similar to parse numbers. Rationale and caveats: * 80 bytes is enough space for a 256-bit integral type (including sign byte and null terminator). It will be a while before processors get past that point. Using buffers large enough for even larger integral types could start running into stack space issues on mobile devices or in threaded environments. We could recommend asprintf, but that means checking for a memory allocation failure for every single integer-to-string conversion, which is pretty burdensome. * We already have a mechanism to ensure that snprintf and asprintf exist. We do not currently have a mechanism to ensure that strlcpy and strlcat exist, and we don't use those in our code base currently. We could add them if we decide we want to allow their use, of course. * strncpy's behavior is too bad to recommend even in cases where truncation is acceptable. * Using memcpy to copy a string constant into a buffer is a pain unless the string constant is short enough that its length is obvious. One option is to define a macro for this case; I'd like to hear discussion before proposing something concrete. * Manual parsing in place of sscanf can be pretty laborious in places, but there aren't a lot of good alternatives. There are only 11 uses of sscanf or fscanf that I counted, so it's not that big of a deal. * I haven't addressed the rand-type functions above. Obviously, using krb_c_random_* is ideal and we already do that in most places. We don't use random/lrand48/rand often and it's generally in a test functions which may not have a krb5 context (although I haven't checked). I think I can just handle these on a case by case basis. From lukeh at padl.com Tue Oct 14 21:47:42 2008 From: lukeh at padl.com (Luke Howard) Date: Wed, 15 Oct 2008 12:47:42 +1100 Subject: "Secure coding" audit checkers and Kerberos In-Reply-To: <200810150106.m9F16QC1004443@outgoing-legacy.mit.edu> References: <200810150106.m9F16QC1004443@outgoing-legacy.mit.edu> Message-ID: > * Instead of strcpy or strcat, use memcpy. Remember to ensure that > the string is terminated if you are not copying a terminator. What about using strlcpy/strlcat (providing implementations for platforms that don't support them). > -- Luke From rra at stanford.edu Tue Oct 14 22:02:22 2008 From: rra at stanford.edu (Russ Allbery) Date: Tue, 14 Oct 2008 19:02:22 -0700 Subject: "Secure coding" audit checkers and Kerberos In-Reply-To: (Luke Howard's message of "Wed\, 15 Oct 2008 12\:47\:42 +1100") References: <200810150106.m9F16QC1004443@outgoing-legacy.mit.edu> Message-ID: <87tzbebopd.fsf@windlord.stanford.edu> Luke Howard writes: >> * Instead of strcpy or strcat, use memcpy. Remember to ensure that >> the string is terminated if you are not copying a terminator. > > What about using strlcpy/strlcat (providing implementations for > platforms that don't support them). I wrote implementations of strlcat and strlcpy for systems that don't have them some time back, along with fairly complete test suites, and released them into the public domain. You're quite welcome to use them. (They're trivial functions, but that saves someone else the effort of writing them and testing them.) Likewise, there's a public domain version of snprintf that I've been using for some time for systems that either don't have snprintf (rare these days) or that have a buggy / pre-C99 version (all versions of Solaris prior to 9). -- Russ Allbery (rra at stanford.edu) From lha at apple.com Tue Oct 14 21:50:57 2008 From: lha at apple.com (=?ISO-8859-1?Q?Love_H=F6rnquist_=C5strand?=) Date: Tue, 14 Oct 2008 18:50:57 -0700 Subject: "Secure coding" audit checkers and Kerberos In-Reply-To: <200810150106.m9F16QC1004443@outgoing-legacy.mit.edu> References: <200810150106.m9F16QC1004443@outgoing-legacy.mit.edu> Message-ID: <12BE5E2B-174B-4CE3-97CD-1526ED8406D1@apple.com> 14 okt 2008 kl. 18:06 skrev ghudson at mit.edu: > * Instead of strcpy or strcat, use memcpy. Remember to ensure that > the string is terminated if you are not copying a terminator. use strlcpy and provide wrapper functions for those that misses it use strlcat and provide wrapper functions for those that misses it important, check for string truncation with both strlcat and strlcpy since that is also a security problem. Using memcpy to copy strings are just backward. Love From raeburn at MIT.EDU Tue Oct 14 22:25:49 2008 From: raeburn at MIT.EDU (Ken Raeburn) Date: Tue, 14 Oct 2008 22:25:49 -0400 Subject: "Secure coding" audit checkers and Kerberos In-Reply-To: References: <200810150106.m9F16QC1004443@outgoing-legacy.mit.edu> Message-ID: <8F395AA6-7552-40B3-8DC7-B672D00AB85A@mit.edu> On Oct 14, 2008, at 21:47, Luke Howard wrote: >> * Instead of strcpy or strcat, use memcpy. Remember to ensure that >> the string is terminated if you are not copying a terminator. > > What about using strlcpy/strlcat (providing implementations for > platforms that don't support them). And then check for truncation, and add error paths or abort calls? As Greg said, silent truncation can lead to security problems just as buffer overruns can. If we skip the truncation tests on the grounds that we've verified the code is consistent and correct in its use of lengths, then either we can just use memcpy, or we're not *that* confident of our checks and should keep the truncation tests. If we put in the tests, now we need error recovery for more than just failed allocation, or we have "assert" or "abort" calls littered through the code, which some coding standards would regard as rather ugly. Personally, my preference is to use small building blocks that can be verified to be correct, and build on them. The "strdup" function is an obvious example, which we already use in a lot of places; "asprintf"/"vasprintf" are hairier (to implement and verify) but also valid examples. I haven't looked at many of the examples, but there are probably other simple things that could be implemented as helper functions, like "copy out krb5_data contents into a null-terminated C string, but (... do something) if there's a null byte in the content". The GSS buffer handling is another issue; we've had a bunch of cases in the past where code used "%s" to print the buffer contents, ignoring the fact that the GSS-API C bindings don't guarantee null termination of strings stored in buffer handles, but "%.*s" can supply the length (when appropriately cast, after range checking) and pointer data together so as to avoid overrunning the buffer. (Should check on this: I'm not certain *printf are required not to read past N bytes, though they are required not to output more than that.) Ken From lukeh at padl.com Tue Oct 14 22:30:28 2008 From: lukeh at padl.com (Luke Howard) Date: Wed, 15 Oct 2008 13:30:28 +1100 Subject: "Secure coding" audit checkers and Kerberos In-Reply-To: <87tzbebopd.fsf@windlord.stanford.edu> References: <200810150106.m9F16QC1004443@outgoing-legacy.mit.edu> <87tzbebopd.fsf@windlord.stanford.edu> Message-ID: > Likewise, there's a public domain version of snprintf that I've been > using > for some time for systems that either don't have snprintf (rare these > days) or that have a buggy / pre-C99 version (all versions of Solaris > prior to 9). So, did Sun change the return value in Solaris 9? snprintf() first appeared on Solaris 2.6 but its behaviour differs to most other platforms, in that it returns the number of bytes that would have been written regardless of buffer size. -- Luke From rra at stanford.edu Tue Oct 14 22:36:52 2008 From: rra at stanford.edu (Russ Allbery) Date: Tue, 14 Oct 2008 19:36:52 -0700 Subject: "Secure coding" audit checkers and Kerberos In-Reply-To: <8F395AA6-7552-40B3-8DC7-B672D00AB85A@mit.edu> (Ken Raeburn's message of "Tue\, 14 Oct 2008 22\:25\:49 -0400") References: <200810150106.m9F16QC1004443@outgoing-legacy.mit.edu> <8F395AA6-7552-40B3-8DC7-B672D00AB85A@mit.edu> Message-ID: <87d4i2a8jf.fsf@windlord.stanford.edu> Ken Raeburn writes: > And then check for truncation, and add error paths or abort calls? As > Greg said, silent truncation can lead to security problems just as > buffer overruns can. If we skip the truncation tests on the grounds > that we've verified the code is consistent and correct in its use of > lengths, then either we can just use memcpy, or we're not *that* > confident of our checks and should keep the truncation tests. If we put > in the tests, now we need error recovery for more than just failed > allocation, or we have "assert" or "abort" calls littered through the > code, which some coding standards would regard as rather ugly. It sounds like one of the root problems is not so much what functions you use as having a uniform error handling method. Every approach requires error handling. If you find a general solution to error handling, then you can take that out of the set of things you have to worry about, and more options come into play (such as using asprintf/vasprintf everywhere you have variable-length output instead of trying to decide on a static buffer size). Perhaps standardizing on an error handling strategy in all functions would help? Then you could do things such as using macros for common actions that check errors and use goto to jump to a cleanup and exit label (sort of an exception method implemented in C). -- Russ Allbery (rra at stanford.edu) From rra at stanford.edu Tue Oct 14 22:39:31 2008 From: rra at stanford.edu (Russ Allbery) Date: Tue, 14 Oct 2008 19:39:31 -0700 Subject: "Secure coding" audit checkers and Kerberos In-Reply-To: (Luke Howard's message of "Wed\, 15 Oct 2008 13\:30\:28 +1100") References: <200810150106.m9F16QC1004443@outgoing-legacy.mit.edu> <87tzbebopd.fsf@windlord.stanford.edu> Message-ID: <878wsqa8f0.fsf@windlord.stanford.edu> Luke Howard writes: >> Likewise, there's a public domain version of snprintf that I've been >> using for some time for systems that either don't have snprintf (rare >> these days) or that have a buggy / pre-C99 version (all versions of >> Solaris prior to 9). > > So, did Sun change the return value in Solaris 9? Yes, or perhaps Solaris 10. I know they changed it, but don't remember the point when that happened. > snprintf() first appeared on Solaris 2.6 but its behaviour differs to > most other platforms, in that it returns the number of bytes that would > have been written regardless of buffer size. I think you accidentally got that backwards. That's the behavior everywhere else, and is required by C99, but Solaris returned -1 instead. The other thing to watch out for with snprintf is that some implementations (older Solaris again, IIRC) don't allow the size to be 0 and str to be NULL to get a count of how much space would be required. -- Russ Allbery (rra at stanford.edu) From raeburn at MIT.EDU Tue Oct 14 22:59:39 2008 From: raeburn at MIT.EDU (Ken Raeburn) Date: Tue, 14 Oct 2008 22:59:39 -0400 Subject: "Secure coding" audit checkers and Kerberos In-Reply-To: <200810150106.m9F16QC1004443@outgoing-legacy.mit.edu> References: <200810150106.m9F16QC1004443@outgoing-legacy.mit.edu> Message-ID: On Oct 14, 2008, at 21:06, ghudson at MIT.EDU wrote: > * Instead of using sprintf to convert an integral type into a string, > use snprintf with an 80-byte buffer. If you want to make it explicit, define a macro that computes the size using LOG10_OF_256*nbytes, rounding up, adding in the extra bytes. Looks a bit more complicated, but not as arbitrary. We could also trivially apply it to the maximum size of "long long", "size_t", "uintmax_t", etc., and use much less space on our current platforms. I think we already have something along these lines in one or two places; look for "log10". > * We already have a mechanism to ensure that snprintf and asprintf > exist. We do not currently have a mechanism to ensure that strlcpy > and strlcat exist, and we don't use those in our code base > currently. We could add them if we decide we want to allow their > use, of course. Actually, we require snprintf currently except on Windows; asprintf we can fudge easily enough. I looked at some implementations of snprintf floating around, but they were pretty much all full implementations, not something cleverly (or not so cleverly) layered on top of the support already present in the OS, and that seemed a bit heavy-weight. We could probably fudge it (open /dev/null, fprintf to it, check the returned length, if it's bigger than the supplied length allocate a temporary buffer, call sprintf); it's not very pretty and it imposes a performance penalty on the older platforms that don't have snprintf, but it's lighter-weight than carrying a full *printf implementation. > * I haven't addressed the rand-type functions above. Obviously, using > krb_c_random_* is ideal and we already do that in most places. We > don't use random/lrand48/rand often and it's generally in a test > functions which may not have a krb5 context (although I haven't > checked). I think I can just handle these on a case by case basis. If we're using rand-type functions, consider whether reproducibility is desirable in those cases; that's a significant difference between them and the Yarrow-based PRNG we've got, the latter will get data from /dev/urandom and results won't be easily reproducible. Ken From lukeh at padl.com Tue Oct 14 23:11:12 2008 From: lukeh at padl.com (Luke Howard) Date: Wed, 15 Oct 2008 14:11:12 +1100 Subject: "Secure coding" audit checkers and Kerberos In-Reply-To: <878wsqa8f0.fsf@windlord.stanford.edu> References: <200810150106.m9F16QC1004443@outgoing-legacy.mit.edu> <87tzbebopd.fsf@windlord.stanford.edu> <878wsqa8f0.fsf@windlord.stanford.edu> Message-ID: <3ED9C62F-0027-4244-9C51-2828773406F6@padl.com> >> snprintf() first appeared on Solaris 2.6 but its behaviour differs to >> most other platforms, in that it returns the number of bytes that >> would >> have been written regardless of buffer size. > > I think you accidentally got that backwards. That's the behavior > everywhere else, and is required by C99, but Solaris returned -1 > instead. My bad, sorry! -- Luke From raeburn at MIT.EDU Tue Oct 14 23:19:47 2008 From: raeburn at MIT.EDU (Ken Raeburn) Date: Tue, 14 Oct 2008 23:19:47 -0400 Subject: "Secure coding" audit checkers and Kerberos In-Reply-To: <87d4i2a8jf.fsf@windlord.stanford.edu> References: <200810150106.m9F16QC1004443@outgoing-legacy.mit.edu> <8F395AA6-7552-40B3-8DC7-B672D00AB85A@mit.edu> <87d4i2a8jf.fsf@windlord.stanford.edu> Message-ID: On Oct 14, 2008, at 22:36, Russ Allbery wrote: > It sounds like one of the root problems is not so much what > functions you > use as having a uniform error handling method. Every approach > requires > error handling. If you find a general solution to error handling, > then > you can take that out of the set of things you have to worry about, > and > more options come into play (such as using asprintf/vasprintf > everywhere > you have variable-length output instead of trying to decide on a > static > buffer size). I'd rather see the simple things constructed such that the possible errors are minimized or (except for allocation failures) eliminated. I don't think we necessarily want one error handling strategy that provides the flexibility to pass back a dozen or more different possible errors from a ticket request to also be the way we indicate that a strdup-type function encountered its only possible error, inability to allocate storage. (Though I'm assuming that at that level we don't want friendly checks for NULL inputs that generate EINVAL or something.) And depending on what sort of string operations Greg finds are commonly being done, I think we can probably make building blocks that can easily be reviewed and shown not to be able to produce any errors beside allocation failures. (Cases where we might prefer truncation over huge outputs are another story, of course.) Ken From ghudson at MIT.EDU Tue Oct 14 23:32:00 2008 From: ghudson at MIT.EDU (Greg Hudson) Date: Tue, 14 Oct 2008 23:32:00 -0400 Subject: "Secure coding" audit checkers and Kerberos In-Reply-To: <87d4i2a8jf.fsf@windlord.stanford.edu> References: <200810150106.m9F16QC1004443@outgoing-legacy.mit.edu> <8F395AA6-7552-40B3-8DC7-B672D00AB85A@mit.edu> <87d4i2a8jf.fsf@windlord.stanford.edu> Message-ID: <1224041520.6796.157.camel@error-messages.mit.edu> I'm trying to let this conversation run its course for a bit without responding to every message, but I do want to raise one point for further discussion. On Tue, 2008-10-14 at 19:36 -0700, Russ Allbery wrote: > Every approach requires error handling. For the usual case (concatenation), this is usually true. Either you're allocating a buffer, in which case you have to check for allocation failure, or you're using a fixed-sized buffer, in which case you have to check for overflow. Note that in both cases, you have to measure the length of the source strings, which gives you the material you need for a later memcpy(), which is why I favor that approach. There are some simple cases which do not require error handling. Copying a short constant string into a big buffer is one. Formatting an integer into a "big enough" buffer is arguably another. When error handling is necessary, it's often better if there is one error path and not many. If we are concatenating three strings into an allocated buffer, I do not want to see unreachable and untestable error paths on each of the three string-copy calls. From Nicolas.Williams at sun.com Wed Oct 15 00:08:02 2008 From: Nicolas.Williams at sun.com (Nicolas Williams) Date: Tue, 14 Oct 2008 23:08:02 -0500 Subject: "Secure coding" audit checkers and Kerberos In-Reply-To: References: <200810150106.m9F16QC1004443@outgoing-legacy.mit.edu> Message-ID: <20081015040802.GP8906@Sun.COM> On Wed, Oct 15, 2008 at 12:47:42PM +1100, Luke Howard wrote: > > * Instead of strcpy or strcat, use memcpy. Remember to ensure that > > the string is terminated if you are not copying a terminator. > > What about using strlcpy/strlcat (providing implementations for > platforms that don't support them). +1. I don't see the benefit of memcpy() vs. strcpy() unless you're effectively building a set of strl*()-like utility functions. From Nicolas.Williams at sun.com Wed Oct 15 00:09:30 2008 From: Nicolas.Williams at sun.com (Nicolas Williams) Date: Tue, 14 Oct 2008 23:09:30 -0500 Subject: "Secure coding" audit checkers and Kerberos In-Reply-To: <878wsqa8f0.fsf@windlord.stanford.edu> References: <200810150106.m9F16QC1004443@outgoing-legacy.mit.edu> <87tzbebopd.fsf@windlord.stanford.edu> <878wsqa8f0.fsf@windlord.stanford.edu> Message-ID: <20081015040929.GQ8906@Sun.COM> On Tue, Oct 14, 2008 at 07:39:31PM -0700, Russ Allbery wrote: > Luke Howard writes: > > >> Likewise, there's a public domain version of snprintf that I've been > >> using for some time for systems that either don't have snprintf (rare > >> these days) or that have a buggy / pre-C99 version (all versions of > >> Solaris prior to 9). > > > > So, did Sun change the return value in Solaris 9? > > Yes, or perhaps Solaris 10. I know they changed it, but don't remember > the point when that happened. It changed in S10. It may have been backported for all I know. From john at iastate.edu Wed Oct 15 00:35:43 2008 From: john at iastate.edu (John Hascall) Date: Tue, 14 Oct 2008 23:35:43 CDT Subject: "Secure coding" audit checkers and Kerberos In-Reply-To: Your message of Tue, 14 Oct 2008 23:32:00 -0400. <1224041520.6796.157.camel@error-messages.mit.edu> Message-ID: <30435.1224045343@malison.ait.iastate.edu> > When error handling is necessary, it's often better if there is one > error path and not many. If we are concatenating three strings into an > allocated buffer, I do not want to see unreachable and untestable error > paths on each of the three string-copy calls. It seems to me that here is where static analysis tools, (like Coverity's), can be a help. John From jhutz at cmu.edu Wed Oct 15 11:54:18 2008 From: jhutz at cmu.edu (Jeffrey Hutzelman) Date: Wed, 15 Oct 2008 11:54:18 -0400 Subject: "Secure coding" audit checkers and Kerberos In-Reply-To: <200810150240.m9F2egnL024078@raisinbran.srv.cs.cmu.edu> References: <200810150106.m9F16QC1004443@outgoing-legacy.mit.edu> <87tzbebopd.fsf@windlord.stanford.edu> <200810150240.m9F2egnL024078@raisinbran.srv.cs.cmu.edu> Message-ID: <80EE5718D624345100585079@atlantis.pc.cs.cmu.edu> --On Tuesday, October 14, 2008 07:39:31 PM -0700 Russ Allbery wrote: > Luke Howard writes: > >>> Likewise, there's a public domain version of snprintf that I've been >>> using for some time for systems that either don't have snprintf (rare >>> these days) or that have a buggy / pre-C99 version (all versions of >>> Solaris prior to 9). >> >> So, did Sun change the return value in Solaris 9? > > Yes, or perhaps Solaris 10. I know they changed it, but don't remember > the point when that happened. > >> snprintf() first appeared on Solaris 2.6 but its behaviour differs to >> most other platforms, in that it returns the number of bytes that would >> have been written regardless of buffer size. > > I think you accidentally got that backwards. That's the behavior > everywhere else, and is required by C99, but Solaris returned -1 instead. > > The other thing to watch out for with snprintf is that some > implementations (older Solaris again, IIRC) don't allow the size to be 0 > and str to be NULL to get a count of how much space would be required. The simple answer here is that the return value of snprintf simply cannot be relied upon, unless it has been tested. In fact, it's not just Solaris that returned -1 when the buffer is too small; they were just late to change. Many platforms used to behave that way. The same goes for the 0/0 call to determine the size, the results of which were undefined before C99. -- Jeff From rra at stanford.edu Wed Oct 15 14:51:52 2008 From: rra at stanford.edu (Russ Allbery) Date: Wed, 15 Oct 2008 11:51:52 -0700 Subject: "Secure coding" audit checkers and Kerberos In-Reply-To: <80EE5718D624345100585079@atlantis.pc.cs.cmu.edu> (Jeffrey Hutzelman's message of "Wed\, 15 Oct 2008 11\:54\:18 -0400") References: <200810150106.m9F16QC1004443@outgoing-legacy.mit.edu> <87tzbebopd.fsf@windlord.stanford.edu> <200810150240.m9F2egnL024078@raisinbran.srv.cs.cmu.edu> <80EE5718D624345100585079@atlantis.pc.cs.cmu.edu> Message-ID: <87tzbdpu7r.fsf@windlord.stanford.edu> Jeffrey Hutzelman writes: > The simple answer here is that the return value of snprintf simply cannot > be relied upon, unless it has been tested. In fact, it's not just Solaris > that returned -1 when the buffer is too small; they were just late to > change. Many platforms used to behave that way. The same goes for the > 0/0 call to determine the size, the results of which were undefined before > C99. Right, all my software that uses snprintf probes the return value in Autoconf and then uses a replacement snprintf implementation if the return value doesn't follow C99. -- Russ Allbery (rra at stanford.edu) From ghudson at MIT.EDU Wed Oct 15 14:54:09 2008 From: ghudson at MIT.EDU (Greg Hudson) Date: Wed, 15 Oct 2008 14:54:09 -0400 Subject: "Secure coding" audit checkers and Kerberos In-Reply-To: <20081015040802.GP8906@Sun.COM> References: <200810150106.m9F16QC1004443@outgoing-legacy.mit.edu> <20081015040802.GP8906@Sun.COM> Message-ID: <1224096849.6796.183.camel@error-messages.mit.edu> On Tue, 2008-10-14 at 23:08 -0500, Nicolas Williams wrote: > +1. I don't see the benefit of memcpy() vs. strcpy() unless you're > effectively building a set of strl*()-like utility functions. I'm hearing that the external-to-MIT Kerberos developer community likes strlcpy. I will probably accede to this preference since it's not really important, but I want to go around on it once more because there's also significant anti-strlcpy sentiment in parts of the C programming community. Ulrich Drepper wrote, in one of his more tactful moments: Correct string handling means that you always know how long your strings are and therefore you can you memcpy (instead of strcpy). To expand on his point: you cannot judge the security of string manipulation code by the individual statements involved. Either the code is correctly considering the lengths of the strings involved or it's not. If you replace a bad strcpy() or memcpy() call with an unchecked strlcpy() call, you will simply replace a potential buffer overrun with a potential truncation, which is still a bug and possibly a security bug. Using memcpy() is not a guarantee of safety, but it does indicate that you're considering the lengths of the strings you're copying. The main benefit over strcpy, though, is an artificial one: it does not get flagged by lint and similar tools. Part of the disconnect within the C community is that the pro-strlcpy crowd typically envisions checked usages while the anti-strlcpy crowd typically envisions unchecked usages. One glibc maintainer went so far as to call strlcat() inefficient because it has to measure the length of the source string for a "rarely-used return value" in the overflow case. If we were to use strlcpy and strlcat in Kerberos, I would expect to have unchecked usages when it is easy to tell that an overflow can't occur. Most of our string manipulation code uses allocated buffers, so I would expect to see code like: buflen = strlen(s1) + strlen(s2) + strlen(s3) + 1; buf = malloc(buflen); if (!buf) return ENOMEM; (void) strlcpy(buf, s1, buflen); (void) strlcat(buf, s2, buflen); (void) strlcat(buf, s3, buflen); Adding an unreachable, untestable error path after each strl*() call in this situation would expand the code size, could force the use of goto-style exception handling in functions which don't otherwise need it, and would inevitably introduce phantom resource leaks which take time to fix. On the other hand, some code which uses fixed-length buffers might actually get prettier if we use strl*() length checks instead of an explicit length check prior to the string operations. (In case anyone is concerned, the vast majority, possibly all, of the Kerberos uses of strcpy() and strcat() are safe for one reason or another. But lint and similar tools have no idea whether this is true, so they just flag all uses of it.) From john at iastate.edu Wed Oct 15 15:17:50 2008 From: john at iastate.edu (John Hascall) Date: Wed, 15 Oct 2008 14:17:50 CDT Subject: "Secure coding" audit checkers and Kerberos In-Reply-To: Your message of Wed, 15 Oct 2008 14:54:09 -0400. <1224096849.6796.183.camel@error-messages.mit.edu> Message-ID: <142.1224098270@malison.ait.iastate.edu> > If we were to use strlcpy and strlcat in Kerberos, I would expect to > have unchecked usages when it is easy to tell that an overflow can't > occur. Most of our string manipulation code uses allocated buffers, so > I would expect to see code like: > > buflen = strlen(s1) + strlen(s2) + strlen(s3) + 1; > buf = malloc(buflen); > if (!buf) return ENOMEM; > (void) strlcpy(buf, s1, buflen); > (void) strlcat(buf, s2, buflen); > (void) strlcat(buf, s3, buflen); > > Adding an unreachable, untestable error path after each strl*() call in > this situation would expand the code size, could force the use of > goto-style exception handling in functions which don't otherwise need > it, and would inevitably introduce phantom resource leaks which take > time to fix. What about hiding that sort of thing in a helper function? something along the lines of: char * vconcat ( char * s1, ... ) { va_list ap; size_t len = 1; size_t off = 0; char * s; char * retval; va_start(ap, s1); for (s = s1; s != NULL; s = va_arg(ap, char *)) { /* XXX: check for overflow of len left as exercise for reader */ len += strlen(s); } va_end(ap); if ((retval = malloc(len)) == NULL) return NULL; va_start(ap, s1); for (s = s1; s != NULL; s = va_arg(ap, char *)) { len = strlen(s); /* XXX: or strlcpy if that's your fancy */ /* XXX: or you could do a byte-by-byte copy to save a pass */ memcpy(retval + off, s, len); off += len; } retval[off] = '\0'; return retval; } then your usage, as shown above, becomes quite clean: if ((buf = vconcat(s1, s2, s3, NULL)) == NULL) return ENOMEM; John PS, I put about 3 minutes into typing that, it may not be perfect, but I trust it gets the idea across. From lha at kth.se Wed Oct 15 16:00:30 2008 From: lha at kth.se (=?ISO-8859-1?Q?Love_H=F6rnquist_=C5strand?=) Date: Wed, 15 Oct 2008 13:00:30 -0700 Subject: "Secure coding" audit checkers and Kerberos In-Reply-To: <1224096849.6796.183.camel@error-messages.mit.edu> References: <200810150106.m9F16QC1004443@outgoing-legacy.mit.edu> <20081015040802.GP8906@Sun.COM> <1224096849.6796.183.camel@error-messages.mit.edu> Message-ID: 15 okt 2008 kl. 11:54 skrev Greg Hudson: > buflen = strlen(s1) + strlen(s2) + strlen(s3) + 1; > buf = malloc(buflen); > if (!buf) return ENOMEM; > (void) strlcpy(buf, s1, buflen); > (void) strlcat(buf, s2, buflen); > (void) strlcat(buf, s3, buflen); asprintf(&buf, "%s%s%s", s1, s2, s3); if (buf == NULL) return ENOMEM; Love From Nicolas.Williams at sun.com Wed Oct 15 15:57:32 2008 From: Nicolas.Williams at sun.com (Nicolas Williams) Date: Wed, 15 Oct 2008 14:57:32 -0500 Subject: "Secure coding" audit checkers and Kerberos In-Reply-To: <1224096849.6796.183.camel@error-messages.mit.edu> References: <200810150106.m9F16QC1004443@outgoing-legacy.mit.edu> <20081015040802.GP8906@Sun.COM> <1224096849.6796.183.camel@error-messages.mit.edu> Message-ID: <20081015195732.GB8906@Sun.COM> On Wed, Oct 15, 2008 at 02:54:09PM -0400, Greg Hudson wrote: > On Tue, 2008-10-14 at 23:08 -0500, Nicolas Williams wrote: > > +1. I don't see the benefit of memcpy() vs. strcpy() unless you're > > effectively building a set of strl*()-like utility functions. > > I'm hearing that the external-to-MIT Kerberos developer community likes > strlcpy. I will probably accede to this preference since it's not > really important, but I want to go around on it once more because > there's also significant anti-strlcpy sentiment in parts of the C > programming community. > > Ulrich Drepper wrote, in one of his more tactful moments: > > Correct string handling means that you always know how long your > strings are and therefore you can you memcpy (instead of > strcpy). I don't agree. With strl*() you need only know the destination buffer's size, and then check the strl*() result to see if truncation/overflow occurred. (As the manpage says: " Buffer overflow can be checked as follows: if (strlcat(dst, src, dstsize) >= dstsize) return -1; " and " ... Buffer overflow can be checked as follows: if (strlcpy(dst, src, dstsize) >= dstsize) return -1; " > To expand on his point: you cannot judge the security of string > manipulation code by the individual statements involved. Either the > code is correctly considering the lengths of the strings involved or > it's not. If you replace a bad strcpy() or memcpy() call with an > unchecked strlcpy() call, you will simply replace a potential buffer > overrun with a potential truncation, which is still a bug and possibly a > security bug. It is clearly not sufficient to replace instances of strcpy() with strlcpy(). Neither is it to replace them with memcpy(). You have to add some code as well. I.e., this: (void) strcpy(dst, src); should be replaced with either: size_t dstsize = ; size_t srcsize = ; if (srcsize >= dstsize) ; else ; or: size_t dstsize = ; if (strlcpy(dst, src, dstsize) >= dstsize) ; The second idiom is simpler than the first. Both are morally equivalent. Simplicity should therefore win. > Using memcpy() is not a guarantee of safety, but it does indicate that > [...] Of course not. The same is true of strncpy(). And strlcpy(). The surrounding code matters. You can simplify the above idioms even more if you can establish some common conventions, like: always malloc() buffers, in which case you could use strdup() and build a astrcat(). You'd then have to be careful not to leak memory, of course. (There's *never* a free lunch in C.) > Part of the disconnect within the C community is that the pro-strlcpy > crowd typically envisions checked usages while the anti-strlcpy crowd > typically envisions unchecked usages. One glibc maintainer went so far > as to call strlcat() inefficient because it has to measure the length of > the source string for a "rarely-used return value" in the overflow case. You can't have unchecked calls to anything here. Either have pre-call checks that guarantee success, or post call error checks, or both. Choose a philosophy and stick to it. But don't claim one allows you to avoid checks. Both require checks. Or re-write in a higher-level labguage that avoids the whole issue ;) > If we were to use strlcpy and strlcat in Kerberos, I would expect to > have unchecked usages when it is easy to tell that an overflow can't > occur. Most of our string manipulation code uses allocated buffers, so > I would expect to see code like: Sure. > buflen = strlen(s1) + strlen(s2) + strlen(s3) + 1; > buf = malloc(buflen); > if (!buf) return ENOMEM; > (void) strlcpy(buf, s1, buflen); > (void) strlcat(buf, s2, buflen); > (void) strlcat(buf, s3, buflen); > > Adding an unreachable, untestable error path after each strl*() call in > this situation would expand the code size, could force the use of > goto-style exception handling in functions which don't otherwise need > it, and would inevitably introduce phantom resource leaks which take > time to fix. That's what assert() is for: buflen = strlen(s1) + strlen(s2) + strlen(s3) + 1; buf = malloc(buflen); if (!buf) return ENOMEM; newlen = strlcpy(buf, s1, buflen); assert(newlen < buflen); newlen = strlcat(buf, s2, buflen); assert(newlen < buflen); newlen = strlcat(buf, s3, buflen); assert(newlen < buflen); If this were a very common idiom you could then build a utility function or macro. If you #define NCHECK then the compiler might optimize away the assignments to newlen. > On the other hand, some code which uses fixed-length buffers might > actually get prettier if we use strl*() length checks instead of an > explicit length check prior to the string operations. Six of one... > (In case anyone is concerned, the vast majority, possibly all, of the > Kerberos uses of strcpy() and strcat() are safe for one reason or > another. But lint and similar tools have no idea whether this is true, > so they just flag all uses of it.) Such tools should probably also flag memcpy(), strlcpy(), ... as well. Without analyzing the code you can't conclude that the code is correct just because it doesn't use a function that's on someone's blaklist. strcpy() can be used safely if you check before calling it. memcpy() cna be used unsafely if the preceding checks are incorrect. If you *really* want to solve the static analysis problem then you need a better model of strings and buffers than the C string model. You might say that you need a better language, but that wouldn't be practical right now. One of the nice things about strl*() is that it's easy to check whether their return values are being checked. I doubt any lint tools exist which statically analyze that: a) the correct dstsize is passed in to strl*(), and b) that the result of strl*() is checked against dstsize, much less c) that the action on overflow is correct. The same, no doubt, is true w.r.t. memcpy() and pre-call checking. But it should be easier to do the static analysis for strl*() than for memcpy() since more useful information is conveyed to the analyzer by the very name and semantics of strl*() than by memcpy()'s. ...half a dozen of the other. One thin-gruel argument against using memcpy() is that it is an abstraction violation. These are *strings* we're talking about, in the codeset of the current locale (see my argument about lint, above). This argument works the other way too: if you're dealing with strings in one specific codeset then you don't want the caller's current locale to have any impact on what actually happens. Of course, I doubt any strl*() implementations do anything odd like, say, composing Unicode codepoints where two strings are concatenated and the first one ends in a combining codepoint, or that they ever will. Nico -- From john at iastate.edu Wed Oct 15 16:16:06 2008 From: john at iastate.edu (John Hascall) Date: Wed, 15 Oct 2008 15:16:06 CDT Subject: "Secure coding" audit checkers and Kerberos In-Reply-To: Your message of Wed, 15 Oct 2008 13:00:30 -0700. Message-ID: <381.1224101766@malison.ait.iastate.edu> > asprintf(&buf, "%s%s%s", s1, s2, s3); > if (buf == NULL) > return ENOMEM; > Love asprintf is a non-standard, and therefore sub-optimally portable, GNU extension -- so you're still stuck writing something else (perhaps your own asprintf implementation, which is far more baggage than one needs to concat a few strings). John From lha at kth.se Wed Oct 15 16:32:32 2008 From: lha at kth.se (=?ISO-8859-1?Q?Love_H=F6rnquist_=C5strand?=) Date: Wed, 15 Oct 2008 13:32:32 -0700 Subject: "Secure coding" audit checkers and Kerberos In-Reply-To: <20081015200728.GC8906@Sun.COM> References: <200810150106.m9F16QC1004443@outgoing-legacy.mit.edu> <20081015040802.GP8906@Sun.COM> <1224096849.6796.183.camel@error-messages.mit.edu> <20081015200728.GC8906@Sun.COM> Message-ID: 15 okt 2008 kl. 13:07 skrev Nicolas Williams: > And if you don't want to malloc() snprintf() Love From Nicolas.Williams at sun.com Wed Oct 15 16:07:28 2008 From: Nicolas.Williams at sun.com (Nicolas Williams) Date: Wed, 15 Oct 2008 15:07:28 -0500 Subject: "Secure coding" audit checkers and Kerberos In-Reply-To: References: <200810150106.m9F16QC1004443@outgoing-legacy.mit.edu> <20081015040802.GP8906@Sun.COM> <1224096849.6796.183.camel@error-messages.mit.edu> Message-ID: <20081015200728.GC8906@Sun.COM> On Wed, Oct 15, 2008 at 01:00:30PM -0700, Love H?rnquist ?strand wrote: > 15 okt 2008 kl. 11:54 skrev Greg Hudson: > > >buflen = strlen(s1) + strlen(s2) + strlen(s3) + 1; > >buf = malloc(buflen); > >if (!buf) return ENOMEM; > >(void) strlcpy(buf, s1, buflen); > >(void) strlcat(buf, s2, buflen); > >(void) strlcat(buf, s3, buflen); > > asprintf(&buf, "%s%s%s", s1, s2, s3); > if (buf == NULL) > return ENOMEM; And if you don't want to malloc() ('cause then you have to remember to free) then: char dst[MAX_SOMETHING_OR_OTHER]; ... if (strlcpy(dst, s1, sizeof (dst)) >= sizeof (dst)) return (KRB5_ERR_SOMETHING_IS_TOO_LONG); if (strlcat(dst, s2, sizeof (dst)) >= sizeof (dst)) return (KRB5_ERR_SOMETHING_IS_TOO_LONG); if (strlcat(dst, s3, sizeof (dst)) >= sizeof (dst)) return (KRB5_ERR_SOMETHING_IS_TOO_LONG); While we're at it, I am concerned about leaks and double-frees, particularly the latter (there have been enough of those). I'd really like to have every function in MIT krb5 that mallocs anything (or calls any function that does, or which ...) coded in a consistent way. Preferably: All pointer variables should be initialized to NULL where they are declared. Ungated free()s should be used if that is portable, else just if (variable != NULL) free(variable). Use a single return at the bottom of the function, with a goto for any failures. Nico -- From raeburn at MIT.EDU Wed Oct 15 16:39:07 2008 From: raeburn at MIT.EDU (Ken Raeburn) Date: Wed, 15 Oct 2008 16:39:07 -0400 Subject: "Secure coding" audit checkers and Kerberos In-Reply-To: <20081015195732.GB8906@Sun.COM> References: <200810150106.m9F16QC1004443@outgoing-legacy.mit.edu> <20081015040802.GP8906@Sun.COM> <1224096849.6796.183.camel@error-messages.mit.edu> <20081015195732.GB8906@Sun.COM> Message-ID: <6BE35F05-78C9-446E-B9AF-64292F7BD373@mit.edu> On Oct 15, 2008, at 15:57, Nicolas Williams wrote: > On Wed, Oct 15, 2008 at 02:54:09PM -0400, Greg Hudson wrote: >> Ulrich Drepper wrote, in one of his more tactful moments: >> >> Correct string handling means that you always know how long >> your >> strings are and therefore you can you memcpy (instead of >> strcpy). > > I don't agree. > > With strl*() you need only know the destination buffer's size, and > then > check the strl*() result to see if truncation/overflow occurred. (As > the manpage says: I said before, I'd want to look at the actual code, but I believe a lot of these case are cases where we've just allocated the buffer, and therefore have just worked out the lengths of the inputs and the size of the output string. (Though in a bunch of such cases, I've already replaced the code with calls to asprintf.) Perhaps Greg can characterize the contexts of the code that some of the tools are complaining about currently though; I don't know if you've been looking in that much detail yet. Ken From raeburn at MIT.EDU Wed Oct 15 16:41:11 2008 From: raeburn at MIT.EDU (Ken Raeburn) Date: Wed, 15 Oct 2008 16:41:11 -0400 Subject: "Secure coding" audit checkers and Kerberos In-Reply-To: <381.1224101766@malison.ait.iastate.edu> References: <381.1224101766@malison.ait.iastate.edu> Message-ID: <0E46ADD4-7202-451E-937F-36FAD1E13017@mit.edu> On Oct 15, 2008, at 16:16, John Hascall wrote: > asprintf is a non-standard, and therefore > sub-optimally portable, GNU extension -- > so you're still stuck writing something else > (perhaps your own asprintf implementation, > which is far more baggage than one needs > to concat a few strings). We already have it, and we do use it for more than just string concatenation, but as long as it's there, we can use it for "collect these strings together and allocate whatever the right amount of space is" easily enough. Ken From john at iastate.edu Wed Oct 15 16:49:05 2008 From: john at iastate.edu (John Hascall) Date: Wed, 15 Oct 2008 15:49:05 CDT Subject: "Secure coding" audit checkers and Kerberos In-Reply-To: Your message of Wed, 15 Oct 2008 15:35:38 -0500. <20081015203538.GH8906@Sun.COM> Message-ID: <272.1224103745@malison.ait.iastate.edu> > On Wed, Oct 15, 2008 at 03:16:06PM -0500, John Hascall wrote: > > > asprintf(&buf, "%s%s%s", s1, s2, s3); > > > if (buf == NULL) > > > return ENOMEM; > > > Love > > asprintf is a non-standard, and therefore > > sub-optimally portable, GNU extension -- > > so you're still stuck writing something else > > (perhaps your own asprintf implementation, > > which is far more baggage than one needs > > to concat a few strings). > I disagree with the "far more baggage" characterization. Particularly > if the alternative is to use memcpy() instead of strcpy(). While I can certainly understand the visceral dislike of memcpy for string copies -- implementing every possible doohicky that can go in a (GNU extended) *printf format string is a whole lot of baggage. John From raeburn at MIT.EDU Wed Oct 15 16:55:36 2008 From: raeburn at MIT.EDU (Ken Raeburn) Date: Wed, 15 Oct 2008 16:55:36 -0400 Subject: "Secure coding" audit checkers and Kerberos In-Reply-To: <272.1224103745@malison.ait.iastate.edu> References: <272.1224103745@malison.ait.iastate.edu> Message-ID: On Oct 15, 2008, at 16:49, John Hascall wrote: >> On Wed, Oct 15, 2008 at 03:16:06PM -0500, John Hascall wrote: >>>> asprintf(&buf, "%s%s%s", s1, s2, s3); >>>> if (buf == NULL) >>>> return ENOMEM; >>>> Love > >>> asprintf is a non-standard, and therefore >>> sub-optimally portable, GNU extension -- >>> so you're still stuck writing something else >>> (perhaps your own asprintf implementation, >>> which is far more baggage than one needs >>> to concat a few strings). > >> I disagree with the "far more baggage" characterization. >> Particularly >> if the alternative is to use memcpy() instead of strcpy(). > > While I can certainly understand the visceral dislike of memcpy > for string copies -- implementing every possible doohicky that > can go in a (GNU extended) *printf format string is a whole lot > of baggage. If you have snprintf, you can build asprintf on top of it, without reimplementing everything. Ken From john at iastate.edu Wed Oct 15 17:05:10 2008 From: john at iastate.edu (John Hascall) Date: Wed, 15 Oct 2008 16:05:10 CDT Subject: "Secure coding" audit checkers and Kerberos In-Reply-To: Your message of Wed, 15 Oct 2008 15:54:26 -0500. <20081015205426.GM8906@Sun.COM> Message-ID: <536.1224104710@malison.ait.iastate.edu> > On Wed, Oct 15, 2008 at 03:49:05PM -0500, John Hascall wrote: > > > I disagree with the "far more baggage" characterization. Particularly > > > if the alternative is to use memcpy() instead of strcpy(). > > > > While I can certainly understand the visceral dislike of memcpy > > for string copies -- implementing every possible doohicky that > > can go in a (GNU extended) *printf format string is a whole lot > > of baggage. > > But you don't need to. You can implement asprintf() ontop of even an > old snprintf() -- just realloc() if snprintf() > the allocated buffer. 1) snprintf is also non-standard 2) there are some horrible snprintf's out there, including ones which do little more than call sprintf! John From Nicolas.Williams at sun.com Wed Oct 15 16:36:00 2008 From: Nicolas.Williams at sun.com (Nicolas Williams) Date: Wed, 15 Oct 2008 15:36:00 -0500 Subject: "Secure coding" audit checkers and Kerberos In-Reply-To: References: <200810150106.m9F16QC1004443@outgoing-legacy.mit.edu> <20081015040802.GP8906@Sun.COM> <1224096849.6796.183.camel@error-messages.mit.edu> <20081015200728.GC8906@Sun.COM> Message-ID: <20081015203559.GI8906@Sun.COM> On Wed, Oct 15, 2008 at 01:32:32PM -0700, Love H?rnquist ?strand wrote: > > 15 okt 2008 kl. 13:07 skrev Nicolas Williams: > > >And if you don't want to malloc() > > snprintf() Point. :) From Nicolas.Williams at sun.com Wed Oct 15 16:54:26 2008 From: Nicolas.Williams at sun.com (Nicolas Williams) Date: Wed, 15 Oct 2008 15:54:26 -0500 Subject: "Secure coding" audit checkers and Kerberos In-Reply-To: <272.1224103745@malison.ait.iastate.edu> References: <20081015203538.GH8906@Sun.COM> <272.1224103745@malison.ait.iastate.edu> Message-ID: <20081015205426.GM8906@Sun.COM> On Wed, Oct 15, 2008 at 03:49:05PM -0500, John Hascall wrote: > > I disagree with the "far more baggage" characterization. Particularly > > if the alternative is to use memcpy() instead of strcpy(). > > While I can certainly understand the visceral dislike of memcpy > for string copies -- implementing every possible doohicky that > can go in a (GNU extended) *printf format string is a whole lot > of baggage. But you don't need to. You can implement asprintf() ontop of even an old snprintf() -- just realloc() if snprintf() > the allocated buffer. Nico -- From Nicolas.Williams at sun.com Wed Oct 15 16:35:38 2008 From: Nicolas.Williams at sun.com (Nicolas Williams) Date: Wed, 15 Oct 2008 15:35:38 -0500 Subject: "Secure coding" audit checkers and Kerberos In-Reply-To: <381.1224101766@malison.ait.iastate.edu> References: <381.1224101766@malison.ait.iastate.edu> Message-ID: <20081015203538.GH8906@Sun.COM> On Wed, Oct 15, 2008 at 03:16:06PM -0500, John Hascall wrote: > > > asprintf(&buf, "%s%s%s", s1, s2, s3); > > if (buf == NULL) > > return ENOMEM; > > Love > > asprintf is a non-standard, and therefore > sub-optimally portable, GNU extension -- > so you're still stuck writing something else > (perhaps your own asprintf implementation, > which is far more baggage than one needs > to concat a few strings). I disagree with the "far more baggage" characterization. Particularly if the alternative is to use memcpy() instead of strcpy(). From tlyu at MIT.EDU Wed Oct 15 17:14:16 2008 From: tlyu at MIT.EDU (Tom Yu) Date: Wed, 15 Oct 2008 17:14:16 -0400 Subject: "Secure coding" audit checkers and Kerberos In-Reply-To: <536.1224104710@malison.ait.iastate.edu> (John Hascall's message of "Wed, 15 Oct 2008 16:05:10 CDT") References: <536.1224104710@malison.ait.iastate.edu> Message-ID: John Hascall writes: >> On Wed, Oct 15, 2008 at 03:49:05PM -0500, John Hascall wrote: >> > > I disagree with the "far more baggage" characterization. Particularly >> > > if the alternative is to use memcpy() instead of strcpy(). >> > >> > While I can certainly understand the visceral dislike of memcpy >> > for string copies -- implementing every possible doohicky that >> > can go in a (GNU extended) *printf format string is a whole lot >> > of baggage. >> >> But you don't need to. You can implement asprintf() ontop of even an >> old snprintf() -- just realloc() if snprintf() > the allocated buffer. > > 1) snprintf is also non-standard snprintf is in C99. Is that good enough for "standard"? > 2) there are some horrible snprintf's out there, > including ones which do little more than call sprintf! What platforms are these on? I think that we do not want to go to extreme lengths working around vulnerabilities in OS C libraries. From john at iastate.edu Wed Oct 15 17:23:54 2008 From: john at iastate.edu (John Hascall) Date: Wed, 15 Oct 2008 16:23:54 CDT Subject: "Secure coding" audit checkers and Kerberos In-Reply-To: Your message of Wed, 15 Oct 2008 17:14:16 -0400. Message-ID: <632.1224105834@malison.ait.iastate.edu> > > 2) there are some horrible snprintf's out there, > > including ones which do little more than call sprintf! > What platforms are these on? I think that we do not want to go to > extreme lengths working around vulnerabilities in OS C libraries. See https://BuildSecurityIn.us-cert.gov/daisy/bsi-rules/home/g1/838-BSI.html John From raeburn at MIT.EDU Wed Oct 15 17:26:06 2008 From: raeburn at MIT.EDU (Ken Raeburn) Date: Wed, 15 Oct 2008 17:26:06 -0400 Subject: "Secure coding" audit checkers and Kerberos In-Reply-To: <536.1224104710@malison.ait.iastate.edu> References: <536.1224104710@malison.ait.iastate.edu> Message-ID: <89A679C3-5BAC-4047-8ACF-BEB8ED8019B9@mit.edu> On Oct 15, 2008, at 17:05, John Hascall wrote: [quoting Nico] >> But you don't need to. You can implement asprintf() ontop of even an >> old snprintf() -- just realloc() if snprintf() > the allocated >> buffer. http://anonsvn.mit.edu/cgi-bin/viewcvs.cgi/trunk/src/util/support/printf.c?rev=20871&view=markup > 1) snprintf is also non-standard It's in C99, SUSv2, and POSIX 2004. Between those and the popular implementations we'd need/want to deal with, we've got somewhat loose specifications on the return value, but otherwise AFAIK they're pretty consistent. > 2) there are some horrible snprintf's out there, > including ones which do little more than call sprintf! Time for a security advisory for that OS, then. We could throw in a configure test -- snprintf to a short automatic buffer with a large amount of stuff to write -- and see if it trashes the stack and crashes the program. If so, refuse to build. A runtime test might be better if binaries get distributed, but wastes cycles for reasonable platforms. We could, if need be, include an snprintf implementation for platforms that either omit or seriously botch it. Enough modern systems have it that I wouldn't be too upset about a quick hack that isn't efficient on those platforms, like I suggested last night. But initially at least I'd be inclined not to worry about it until we hear of specific problems. Ken From rra at stanford.edu Wed Oct 15 17:26:59 2008 From: rra at stanford.edu (Russ Allbery) Date: Wed, 15 Oct 2008 14:26:59 -0700 Subject: "Secure coding" audit checkers and Kerberos In-Reply-To: <381.1224101766@malison.ait.iastate.edu> (John Hascall's message of "Wed\, 15 Oct 2008 15\:16\:06 CDT") References: <381.1224101766@malison.ait.iastate.edu> Message-ID: <87iqrtim70.fsf@windlord.stanford.edu> John Hascall writes: > asprintf is a non-standard, and therefore > sub-optimally portable, GNU extension -- > so you're still stuck writing something else > (perhaps your own asprintf implementation, > which is far more baggage than one needs > to concat a few strings). Provided that you have a C99 snprintf, asprintf is simple to implement. (I have a public domain implementation of that as well that I use for my software.) -- Russ Allbery (rra at stanford.edu) From john at iastate.edu Wed Oct 15 17:29:55 2008 From: john at iastate.edu (John Hascall) Date: Wed, 15 Oct 2008 16:29:55 CDT Subject: "Secure coding" audit checkers and Kerberos In-Reply-To: Your message of Wed, 15 Oct 2008 16:16:18 -0500. <20081015211618.GP8906@Sun.COM> Message-ID: <660.1224106195@malison.ait.iastate.edu> > On Wed, Oct 15, 2008 at 04:05:10PM -0500, John Hascall wrote: > > 1) snprintf is also non-standard > > 2) there are some horrible snprintf's out there, > > including ones which do little more than call sprintf! > The MIT-krb5-uses-snprintf() train departed long ago. So be it, but it does seem a little odd to be worried about a code-analysis tool false-flaging perfectly safe uses of strcpy/strcat and suggesting that the fix is to use some thing known to have a whole array of missing/bad/dangerous implementations. John From Nicolas.Williams at sun.com Wed Oct 15 17:16:18 2008 From: Nicolas.Williams at sun.com (Nicolas Williams) Date: Wed, 15 Oct 2008 16:16:18 -0500 Subject: "Secure coding" audit checkers and Kerberos In-Reply-To: <536.1224104710@malison.ait.iastate.edu> References: <20081015205426.GM8906@Sun.COM> <536.1224104710@malison.ait.iastate.edu> Message-ID: <20081015211618.GP8906@Sun.COM> On Wed, Oct 15, 2008 at 04:05:10PM -0500, John Hascall wrote: > 1) snprintf is also non-standard > 2) there are some horrible snprintf's out there, > including ones which do little more than call sprintf! The MIT-krb5-uses-snprintf() train departed long ago. The Consortium might well decide to [continue to] provide portable versions of these, or that MIT krb5 will not support platforms which do not provide at least working snprintf(). I would support either position. I do object to avoiding *s*printf(). If ultimately that means that MIT krb5 won't run on certain older systems, I really don't care. (And if you think I'm biased, we still support Solaris 9, complete with the onld snprintf() semantics. There is, of course, a bias towards "vendors" or "distros" in what I write above. I don't apologize for it, though I do disclose it.) Nico -- From raeburn at MIT.EDU Wed Oct 15 17:40:49 2008 From: raeburn at MIT.EDU (Ken Raeburn) Date: Wed, 15 Oct 2008 17:40:49 -0400 Subject: "Secure coding" audit checkers and Kerberos In-Reply-To: <632.1224105834@malison.ait.iastate.edu> References: <632.1224105834@malison.ait.iastate.edu> Message-ID: On Oct 15, 2008, at 17:23, John Hascall wrote: > See https://BuildSecurityIn.us-cert.gov/daisy/bsi-rules/home/g1/838-BSI.html That article mentions a few operating systems but doesn't tell us which versions of what systems actually have problems in snprintf. The negative return value we can deal with. The lack of null termination is interesting -- but without discussing *specific* operating systems and versions it's unclear if we need to worry about it. The failure to avoid buffer overflows is a serious problem, and should be addressed by the vendor, but we don't know which that is or what versions of the OSes. They do mention libc4 on Linux, which I doubt anyone uses any more, and even if they do, I'm pretty sure we already use stuff that it doesn't support; they mention "some old HP systems" with even less detail. You could make similar, vague non-portability claims about sprintf; after all, "some old systems" returned char* instead of int, so you really can't use it portably, right? If we've got concrete data of modern systems (or at least systems people are still running, that otherwise provide the facilities we require) with particular problems, we can address them. At some point we need to just tell people to join the 21st^H^H^H^Hlate 90s and run something vaguely compliant with standards and with at least some attention to security. Ken From ghudson at MIT.EDU Wed Oct 15 17:43:44 2008 From: ghudson at MIT.EDU (Greg Hudson) Date: Wed, 15 Oct 2008 17:43:44 -0400 Subject: "Secure coding" audit checkers and Kerberos In-Reply-To: <632.1224105834@malison.ait.iastate.edu> References: <632.1224105834@malison.ait.iastate.edu> Message-ID: <1224107024.6796.189.camel@error-messages.mit.edu> On Wed, 2008-10-15 at 16:23 -0500, John Hascall wrote: > See https://BuildSecurityIn.us-cert.gov/daisy/bsi-rules/home/g1/838-BSI.html This says: 1. Unspecified versions of snprintf() don't protect against buffer overflows. (Possibly elaborated on by the next point; it's unclear.) 2. Old versions of Linux libc4 and "apparently" old HP systems use an implementation with unspecified security issues. 3. The return value varies (so don't use it, or expect both semantics); we know about that. 4. Unspecified versions don't guarantee that the result is terminated. There is one reference, which is a broken link. Except for the return value issue, this is pretty much all FUD. The only implementations actually cited are too old to worry about. From tlyu at MIT.EDU Wed Oct 15 17:47:33 2008 From: tlyu at MIT.EDU (Tom Yu) Date: Wed, 15 Oct 2008 17:47:33 -0400 Subject: "Secure coding" audit checkers and Kerberos In-Reply-To: (Ken Raeburn's message of "Wed, 15 Oct 2008 17:40:49 -0400") References: <632.1224105834@malison.ait.iastate.edu> Message-ID: Ken Raeburn writes: > You could make similar, vague non-portability claims about sprintf; > after all, "some old systems" returned char* instead of int, so you > really can't use it portably, right? If we've got concrete data of > modern systems (or at least systems people are still running, that > otherwise provide the facilities we require) with particular problems, > we can address them. > > At some point we need to just tell people to join the 21st^H^H^H^Hlate > 90s and run something vaguely compliant with standards and with at > least some attention to security. Agreed. See also "Supported platforms" (which I am working on clarifying). I think that our resources can be better spent on modern and security-conscious platforms. From Nicolas.Williams at sun.com Wed Oct 15 17:36:15 2008 From: Nicolas.Williams at sun.com (Nicolas Williams) Date: Wed, 15 Oct 2008 16:36:15 -0500 Subject: "Secure coding" audit checkers and Kerberos In-Reply-To: <660.1224106195@malison.ait.iastate.edu> References: <20081015211618.GP8906@Sun.COM> <660.1224106195@malison.ait.iastate.edu> Message-ID: <20081015213615.GS8906@Sun.COM> On Wed, Oct 15, 2008 at 04:29:55PM -0500, John Hascall wrote: > > The MIT-krb5-uses-snprintf() train departed long ago. > > So be it, but it does seem a little odd to be worried about > a code-analysis tool false-flaging perfectly safe uses of > strcpy/strcat and suggesting that the fix is to use some > thing known to have a whole array of missing/bad/dangerous > implementations. I agree. I think this is not really a necessary excercise unless it is part of a larger styling excercise that aims to prevent lots of unsafe things. Nico -- From john at iastate.edu Wed Oct 15 17:54:48 2008 From: john at iastate.edu (John Hascall) Date: Wed, 15 Oct 2008 16:54:48 CDT Subject: "Secure coding" audit checkers and Kerberos In-Reply-To: Your message of Wed, 15 Oct 2008 17:47:33 -0400. Message-ID: <834.1224107688@malison.ait.iastate.edu> > > At some point we need to just tell people to join the 21st^H^H^H^Hlate > > 90s and run something vaguely compliant with standards and with at > > least some attention to security. > Agreed. See also "Supported platforms" (which I am working on > clarifying). I think that our resources can be better spent on modern > and security-conscious platforms. I also agree IFF either: a) it is known that all supported platforms have safe implementations, or b) it is known which don't and a known safe alternative is provided and used Since "Supported platforms" is, at the moment, somewhat nebulous I'm not sure that statement can be made (at this time). John From since at opendemand.com Wed Oct 15 17:56:04 2008 From: since at opendemand.com (Stephen Ince) Date: Wed, 15 Oct 2008 17:56:04 -0400 Subject: krb5 spnego implementation References: <20081015205426.GM8906@Sun.COM><536.1224104710@malison.ait.iastate.edu> <20081015211618.GP8906@Sun.COM> Message-ID: <54b301c92f10$d25b97d0$6e00a8c0@desktop2> Does the MIT kerberos implementation have a spnego api for win32. Basically I want to support kerberos/spnego http client authentication. I would prefere to use one spnego api for all platforms (win32, linux, or solaris). I have tried fpopenssl but that crashes on win32. Any help would be greatly appreciated. here is some example code. It is based on libcurl. #ifdef HAVE_SPNEGO /* Handle SPNEGO */ if (checkprefix("Negotiate", header)) { : object = OBJ_txt2obj ("1.2.840.113554.1.2.2", 1); if (!parseSpnegoTargetToken(spnegoToken, } else { : } #endif major_status =gss_krb5_ccache_name(&minor_status,krb5->ccache_name, NULL); major_status = gss_init_sec_context(&minor_status, Steve From guenther at gmail.com Wed Oct 15 18:11:34 2008 From: guenther at gmail.com (Philip Guenther) Date: Wed, 15 Oct 2008 15:11:34 -0700 Subject: "Secure coding" audit checkers and Kerberos In-Reply-To: References: <632.1224105834@malison.ait.iastate.edu> Message-ID: On Wed, Oct 15, 2008 at 2:40 PM, Ken Raeburn wrote: ... > They do mention libc4 on Linux, which I doubt anyone uses any more, > and even if they do, I'm pretty sure we already use stuff that it > doesn't support; they mention "some old HP systems" with even less > detail. Specific data point from personal experience: in 2003, HP-UX 11.11's snprintf() had (at least) two defects: 1) it would return -1 if given a non-zero size smaller than the required length. I.e., char c; snprintf(&c, 1, "foo"); would return -1 instead of 3 2) if the size argument was zero, it would act like sprintf() and put no limit on how many characters it would write to the buffer. Philip Guenther From tlyu at MIT.EDU Wed Oct 15 20:06:32 2008 From: tlyu at MIT.EDU (Tom Yu) Date: Wed, 15 Oct 2008 20:06:32 -0400 Subject: security goals re strcpy/strcat/sprintf (Re: "Secure coding" audit checkers and Kerberos) In-Reply-To: <200810150106.m9F16QC1004443@outgoing-legacy.mit.edu> (ghudson@MIT.EDU's message of "Tue, 14 Oct 2008 21:06:26 -0400 (EDT)") References: <200810150106.m9F16QC1004443@outgoing-legacy.mit.edu> Message-ID: ghudson at MIT.EDU writes: > We've been asked to stop using "traditionally insecure" functions > (like strcpy) in order to make krb5 code conform to the standards of > code bases which incorporate it. This thread has generated a lot of traffic, and I would like to refocus our attention on a subset of the topics that have arisen. I would like to clarify why we would like to eliminate or reduce our usage of "unsafe" string functions such as strcpy, strcat, and sprintf. While we have striven to make safe use of these these functions by coding explicit length checking in the surrounding code, some static code analysis tools flag these uses as problems. When these sorts of false positive reports arise, they require us to somehow ensure that the presumed-correct length checking code is actually correct. If this length checking code is widely dispersed throughout the source code, such manual validation can become very time-consuming and error-prone. I acknowledge that the "unsafe" string functions can be used safely and that "safe" string functions can be used unsafely. Regardless, I think there is a meaningful difference between these "safe" and "unsafe" functions. It is easier to determine whether a particular use of "safe" function is actually safe than it is to determine whether a particular use of an "unsafe" function is safe, particularly if the pieces of compensating length checking code, etc. are replicated everywhere the "unsafe" function is used. The vulnerabilities resulting from unsafe uses of the "safe" functions, which could be truncation-related problems, are less severe than those vulnerabilities resulting from unsafe uses of the "unsafe" functions, which are more likely to be buffer overflow type problems. Overall, I think we will end up replacing uses of the "unsafe" string functions with strdup, asprintf, and snprintf. For widely-dispersed and repeated code patterns, we should consider making utility functions to reduce the incidence of programmer error. Some thoughts I've had on the subject, taking into account some of the recent conversation, are below. For replacement candidates that allocate memory, we could consider: * strdup * asprintf For replacement candidates that write into fixed-size buffers, we could consider: * snprintf * strlcpy * strlcat * memcpy snprintf is standard (C99, SUSv3), but some implementations are known to have (hopefully well-characterized by now) problems. asprintf is not standard, but is trivially implementable in terms of snprintf. (as we have already done) strlcpy/strlcat are not standard, and I recall reading allegations that their behavior is not very consistent across implementations. memcpy is standard, but using it with null-terminated strings requires additional calls to strlen and such, which can further complicate automatic or manual inspection. Known issues with the printf family on Solaris include some "interesting" interpretations of the precision field for %s specifiers, such as counting "column width" rather than bytes. This can make dealing with gss_buffer_t and other such explicit-length string-like data structures problematic, depending on the current locale. Nico or other Sun folks, any thoughts on this? Also, I suggest that we refine the description of our supported platforms to include some qualifiers like "includes an implementation of snprintf that is conforming or that is non-conforming in one of a small number of well-characterized ways". -- Tom Yu Development Manager MIT Kerberos Consortium From tlyu at MIT.EDU Wed Oct 15 22:55:40 2008 From: tlyu at MIT.EDU (Tom Yu) Date: Wed, 15 Oct 2008 22:55:40 -0400 Subject: "Secure coding" audit checkers and Kerberos In-Reply-To: <20081015211618.GP8906@Sun.COM> (Nicolas Williams's message of "Wed, 15 Oct 2008 16:16:18 -0500") References: <20081015205426.GM8906@Sun.COM> <536.1224104710@malison.ait.iastate.edu> <20081015211618.GP8906@Sun.COM> Message-ID: Nicolas Williams writes: > On Wed, Oct 15, 2008 at 04:05:10PM -0500, John Hascall wrote: >> 1) snprintf is also non-standard >> 2) there are some horrible snprintf's out there, >> including ones which do little more than call sprintf! > > The MIT-krb5-uses-snprintf() train departed long ago. > > The Consortium might well decide to [continue to] provide portable > versions of these, or that MIT krb5 will not support platforms which do > not provide at least working snprintf(). I would support either > position. > > I do object to avoiding *s*printf(). If ultimately that means that MIT Do you mean to say that you object to *not* avoiding sprintf, i.e., that you object to retaining any uses of sprintf? From Nicolas.Williams at sun.com Wed Oct 15 22:58:00 2008 From: Nicolas.Williams at sun.com (Nicolas Williams) Date: Wed, 15 Oct 2008 21:58:00 -0500 Subject: security goals re strcpy/strcat/sprintf (Re: "Secure coding" audit checkers and Kerberos) In-Reply-To: References: <200810150106.m9F16QC1004443@outgoing-legacy.mit.edu> Message-ID: <20081016025800.GA8906@Sun.COM> On Wed, Oct 15, 2008 at 08:06:32PM -0400, Tom Yu wrote: > I acknowledge that the "unsafe" string functions can be used safely > and that "safe" string functions can be used unsafely. Regardless, I > think there is a meaningful difference between these "safe" and > "unsafe" functions. It is easier to determine whether a particular > use of "safe" function is actually safe than it is to determine > whether a particular use of an "unsafe" function is safe, particularly > if the pieces of compensating length checking code, etc. are > replicated everywhere the "unsafe" function is used. The > vulnerabilities resulting from unsafe uses of the "safe" functions, > which could be truncation-related problems, are less severe than those > vulnerabilities resulting from unsafe uses of the "unsafe" functions, > which are more likely to be buffer overflow type problems. I very much agree with the above. > strlcpy/strlcat are not standard, and I recall reading allegations > that their behavior is not very consistent across implementations. They are quite common now though. I'll look at the alleged difference between Solaris' and BSD' strlcat(). > memcpy is standard, but using it with null-terminated strings requires > additional calls to strlen and such, which can further complicate > automatic or manual inspection. I agree. It's not worth going there (unless avoiding locale issues is important; see below). > Known issues with the printf family on Solaris include some > "interesting" interpretations of the precision field for %s > specifiers, such as counting "column width" rather than bytes. This > can make dealing with gss_buffer_t and other such explicit-length > string-like data structures problematic, depending on the current > locale. Nico or other Sun folks, any thoughts on this? You use a precision field for %s? Where? In any case, the manpage for Solaris' snprintf() says: " If the conversion specifier is s, a standard- conforming application (see standards(5)) inter- prets the field width as the minimum number of bytes to be printed; an application that is not standard-conforming interprets the field width as the minimum number of columns of screen display. For an application that is not standard-conforming, %10s means if the converted value has a screen width of 7 columns, 3 spaces would be padded on the right. " and " If the conversion specifier is s or S, a standard- conforming application (see standards(5)) inter- prets the precision as the maximum number of bytes to be written; an application that is not standard-conforming interprets the precision as the maximum number of columns of screen display. For an application that is not standard-conforming, %.5s would print only the portion of the string that would display in 5 screen columns. Only complete characters are written. " The key here is "standard-conforming application." Figuring out exactly what that means requires looking at standards(5), and maybe some source. Looking at standards(5) I see nothing that clarifies this. I'll file a manpage bug -- the specific standard that applies really should be documented in the *printf() manpage. So looking at source I see: /* * sec_display only needed if width * is specified (ie, "%s") * Solaris behavior counts in * screen column width. (If XPG4 * behavior, * is counted in bytes.) */ and: } else if (__xpg4 == 0 && MB_CUR_MAX > 1) { ... } else { /* * XPG4 behavior - count * precision as bytes. * We don't use strlen() because * the given char string may not * be null-terminated. */ and: * __xpg4 == 0 by default. The xpg4 cc driver will add an object * file that contains int __xpg4 = 1". The symbol interposition * provided by the linker will allow libc to find that symbol * instead. In other words, compile and link using the XPG4 or XPG6 options and you'll get the standard byte-counting, rather than column-counting behavior. I'm not sure what this means for _libraries_, however. I'm not sure whether libraries can have their own __xpg4 interposer that is local to their link map group. I'll inquire and let you know. Having this behavior selected by the application could certainly cause problems. > Also, I suggest that we refine the description of our supported > platforms to include some qualifiers like "includes an implementation > of snprintf that is conforming or that is non-conforming in one of a > small number of well-characterized ways". +1 Nico -- From Nicolas.Williams at sun.com Wed Oct 15 23:04:46 2008 From: Nicolas.Williams at sun.com (Nicolas Williams) Date: Wed, 15 Oct 2008 22:04:46 -0500 Subject: security goals re strcpy/strcat/sprintf (Re: "Secure coding" audit checkers and Kerberos) In-Reply-To: <20081016025800.GA8906@Sun.COM> References: <200810150106.m9F16QC1004443@outgoing-legacy.mit.edu> <20081016025800.GA8906@Sun.COM> Message-ID: <20081016030446.GH9401@Sun.COM> On Wed, Oct 15, 2008 at 09:58:00PM -0500, Nicolas Williams wrote: > On Wed, Oct 15, 2008 at 08:06:32PM -0400, Tom Yu wrote: > > Known issues with the printf family on Solaris include some > > "interesting" interpretations of the precision field for %s > > specifiers, such as counting "column width" rather than bytes. This > > can make dealing with gss_buffer_t and other such explicit-length > > string-like data structures problematic, depending on the current > > locale. Nico or other Sun folks, any thoughts on this? > > [...] > > In other words, compile and link using the XPG4 or XPG6 options and > you'll get the standard byte-counting, rather than column-counting > behavior. > > I'm not sure what this means for _libraries_, however. I'm not sure > whether libraries can have their own __xpg4 interposer that is local to > their link map group. I'll inquire and let you know. Having this > behavior selected by the application could certainly cause problems. Sorry, I should have instantly known the answer. No, the library cannot differently interpose on libc's view of the __xpg4 symbol. Therefore the compilation/link options of the _application_ govern the standards-compliance of *s*printf() with regards to string precision (but not with regards to return value). I'll file a bug about that too. That behavor strikes me as not a good idea given library use of these functions. Nico -- From Nicolas.Williams at sun.com Wed Oct 15 23:00:17 2008 From: Nicolas.Williams at sun.com (Nicolas Williams) Date: Wed, 15 Oct 2008 22:00:17 -0500 Subject: "Secure coding" audit checkers and Kerberos In-Reply-To: References: <20081015205426.GM8906@Sun.COM> <536.1224104710@malison.ait.iastate.edu> <20081015211618.GP8906@Sun.COM> Message-ID: <20081016030016.GB8906@Sun.COM> On Wed, Oct 15, 2008 at 10:55:40PM -0400, Tom Yu wrote: > Nicolas Williams writes: > > > On Wed, Oct 15, 2008 at 04:05:10PM -0500, John Hascall wrote: > >> 1) snprintf is also non-standard > >> 2) there are some horrible snprintf's out there, > >> including ones which do little more than call sprintf! > > > > The MIT-krb5-uses-snprintf() train departed long ago. > > > > The Consortium might well decide to [continue to] provide portable > > versions of these, or that MIT krb5 will not support platforms which do > > not provide at least working snprintf(). I would support either > > position. > > > > I do object to avoiding *s*printf(). If ultimately that means that MIT > > Do you mean to say that you object to *not* avoiding sprintf, i.e., > that you object to retaining any uses of sprintf? No, I meant what I wrote. I object to *s*printf() avoidance. I do realize that that means checking for the correctness of a platform's implementation, and it might mean avoiding precision specifiers for %s (but I've not settled that yet; see my other reply). From tlyu at MIT.EDU Wed Oct 15 23:33:33 2008 From: tlyu at MIT.EDU (Tom Yu) Date: Wed, 15 Oct 2008 23:33:33 -0400 Subject: "Secure coding" audit checkers and Kerberos In-Reply-To: <20081016030016.GB8906@Sun.COM> (Nicolas Williams's message of "Wed, 15 Oct 2008 22:00:17 -0500") References: <20081015205426.GM8906@Sun.COM> <536.1224104710@malison.ait.iastate.edu> <20081015211618.GP8906@Sun.COM> <20081016030016.GB8906@Sun.COM> Message-ID: Nicolas Williams writes: > On Wed, Oct 15, 2008 at 10:55:40PM -0400, Tom Yu wrote: >> Nicolas Williams writes: >> >> > On Wed, Oct 15, 2008 at 04:05:10PM -0500, John Hascall wrote: >> >> 1) snprintf is also non-standard >> >> 2) there are some horrible snprintf's out there, >> >> including ones which do little more than call sprintf! >> > >> > The MIT-krb5-uses-snprintf() train departed long ago. >> > >> > The Consortium might well decide to [continue to] provide portable >> > versions of these, or that MIT krb5 will not support platforms which do >> > not provide at least working snprintf(). I would support either >> > position. >> > >> > I do object to avoiding *s*printf(). If ultimately that means that MIT >> >> Do you mean to say that you object to *not* avoiding sprintf, i.e., >> that you object to retaining any uses of sprintf? > > No, I meant what I wrote. I object to *s*printf() avoidance. I do > realize that that means checking for the correctness of a platform's > implementation, and it might mean avoiding precision specifiers for %s > (but I've not settled that yet; see my other reply). Oh. Do you mean the sprintf family of functions, rather than the sprintf function in particular? I may have misread your asterisks as emphasis around the letter "s" rather than as globs. I understand why you might prefer using one of the sprintf functions to using some unwieldy sequence of invocations of strcpy and strcat (or strlcpy and strlcat). From ghudson at MIT.EDU Wed Oct 15 23:55:03 2008 From: ghudson at MIT.EDU (Greg Hudson) Date: Wed, 15 Oct 2008 23:55:03 -0400 Subject: security goals re strcpy/strcat/sprintf (Re: "Secure coding" audit checkers and Kerberos) In-Reply-To: <20081016025800.GA8906@Sun.COM> References: <200810150106.m9F16QC1004443@outgoing-legacy.mit.edu> <20081016025800.GA8906@Sun.COM> Message-ID: <1224129303.6796.210.camel@error-messages.mit.edu> On Wed, 2008-10-15 at 21:58 -0500, Nicolas Williams wrote: > You use a precision field for %s? Where? Not often. Precision fields: ./src/kadmin/ktutil/ktutil_funcs.c: sprintf(promptstr, "Password for %.1000s", princ_str); ./src/kadmin/cli/kadmin.c: sprintf(prompt1, "Enter password for principal \"%.900s\"", ./src/kadmin/cli/kadmin.c: "Re-enter password for principal \"%.900s\"", ./src/kadmin/cli/kadmin.c: sprintf(prompt1, "Enter password for principal \"%.900s\"", ./src/kadmin/cli/kadmin.c: "Re-enter password for principal \"%.900s\"", The precision field in those uses can probably be removed if the calls are switched to use snprintf. We use field widths with %s in 33 places, but it's all printf and fprintf, not sprintf. Mostly in plugins/kdb. > They are quite common now though. I'll look at the alleged difference > between Solaris' and BSD' strlcat(). Wikipedia says this: there are implementation differences between the BSD and Solaris implementations (the return value of strlcat when there is no nul in the destination buffer) A destination buffer containing no nul character would be invalid input to the strlcat command. This is no more worrisome than, say, memcpy() having unspecified behavior when the source and destination buffers overlap. On another note, I have done a spot check of the uses of strcpy and strcat in the krb5 source tree, and a great many of them appear to be easily replaced with either strdup() or asprintf(), reducing the code size in the process. There are some exceptions, but it might be easier to decide on an approach for the exceptions after eliminating the common, easy cases. From Nicolas.Williams at sun.com Thu Oct 16 00:28:36 2008 From: Nicolas.Williams at sun.com (Nicolas Williams) Date: Wed, 15 Oct 2008 23:28:36 -0500 Subject: security goals re strcpy/strcat/sprintf (Re: "Secure coding" audit checkers and Kerberos) In-Reply-To: <1224129303.6796.210.camel@error-messages.mit.edu> References: <200810150106.m9F16QC1004443@outgoing-legacy.mit.edu> <20081016025800.GA8906@Sun.COM> <1224129303.6796.210.camel@error-messages.mit.edu> Message-ID: <20081016042836.GC8906@Sun.COM> On Wed, Oct 15, 2008 at 11:55:03PM -0400, Greg Hudson wrote: > On Wed, 2008-10-15 at 21:58 -0500, Nicolas Williams wrote: > > You use a precision field for %s? Where? > > Not often. Precision fields: > > ./src/kadmin/ktutil/ktutil_funcs.c: sprintf(promptstr, "Password for %.1000s", princ_str); > ./src/kadmin/cli/kadmin.c: sprintf(prompt1, "Enter password for principal \"%.900s\"", > ./src/kadmin/cli/kadmin.c: "Re-enter password for principal \"%.900s\"", > ./src/kadmin/cli/kadmin.c: sprintf(prompt1, "Enter password for principal \"%.900s\"", > ./src/kadmin/cli/kadmin.c: "Re-enter password for principal \"%.900s\"", > > The precision field in those uses can probably be removed if the calls > are switched to use snprintf. Yeah, those are all sprintf() calls. You shouldn't use sprintf(). (Yes, I wrote in favor of using *s*printf(), but I should have qualified that to exclude sprintf() itself.) > We use field widths with %s in 33 places, but it's all printf and > fprintf, not sprintf. Mostly in plugins/kdb. I don't think that's a big deal if the output is intended for humans, but if the fprintf()s are to files and those can be re-read, that could be an issue. > On another note, I have done a spot check of the uses of strcpy and > strcat in the krb5 source tree, and a great many of them appear to be > easily replaced with either strdup() or asprintf(), reducing the code > size in the process. There are some exceptions, but it might be easier > to decide on an approach for the exceptions after eliminating the > common, easy cases. I agree. From ssorce at redhat.com Thu Oct 16 05:32:15 2008 From: ssorce at redhat.com (Simo Sorce) Date: Thu, 16 Oct 2008 05:32:15 -0400 Subject: "Secure coding" audit checkers and Kerberos In-Reply-To: <20081016030016.GB8906@Sun.COM> References: <20081015205426.GM8906@Sun.COM> <536.1224104710@malison.ait.iastate.edu> <20081015211618.GP8906@Sun.COM> <20081016030016.GB8906@Sun.COM> Message-ID: <1224149535.28298.90.camel@hopeson> On Wed, 2008-10-15 at 22:00 -0500, Nicolas Williams wrote: > On Wed, Oct 15, 2008 at 10:55:40PM -0400, Tom Yu wrote: > > Nicolas Williams writes: > > > > > On Wed, Oct 15, 2008 at 04:05:10PM -0500, John Hascall wrote: > > >> 1) snprintf is also non-standard > > >> 2) there are some horrible snprintf's out there, > > >> including ones which do little more than call sprintf! > > > > > > The MIT-krb5-uses-snprintf() train departed long ago. > > > > > > The Consortium might well decide to [continue to] provide portable > > > versions of these, or that MIT krb5 will not support platforms which do > > > not provide at least working snprintf(). I would support either > > > position. > > > > > > I do object to avoiding *s*printf(). If ultimately that means that MIT > > > > Do you mean to say that you object to *not* avoiding sprintf, i.e., > > that you object to retaining any uses of sprintf? > > No, I meant what I wrote. I object to *s*printf() avoidance. I do > realize that that means checking for the correctness of a platform's > implementation, and it might mean avoiding precision specifiers for %s > (but I've not settled that yet; see my other reply). After almost 10 years from C99 avoiding it would be just absurd if you ask me. If there are platforms that really can't cope with C99 after 10 years I honestly think nobody should consider using them as a KDC anyway. I think you might even decide not to provide substitute functions, but just have configure tests and refuse to build if they do not pass. *If* it turns out a large number of platforms do not work then you may decide to implement substitute functions for the ones you use that fail. /Simo who has written C99 snprintf() substitute functions too, like many here, and thinks it is really time vendors update their stuff or die off. From john at iastate.edu Thu Oct 16 07:47:28 2008 From: john at iastate.edu (John Hascall) Date: Thu, 16 Oct 2008 06:47:28 CDT Subject: "Secure coding" audit checkers and Kerberos In-Reply-To: Your message of Thu, 16 Oct 2008 05:32:15 -0400. <1224149535.28298.90.camel@hopeson> Message-ID: <3067.1224157648@malison.ait.iastate.edu> > If there are platforms that really can't cope with C99 after 10 > years I honestly think nobody should consider using them as a KDC > anyway. OK. But do remember that KDCs aren't much use without clients. (I'm pretty sure I had to supply a snprintf to get it to build for our DEC Alpha clients [which still number almost 100 I think!] some time back). John From tlyu at MIT.EDU Thu Oct 16 08:36:21 2008 From: tlyu at MIT.EDU (Tom Yu) Date: Thu, 16 Oct 2008 08:36:21 -0400 Subject: security goals re strcpy/strcat/sprintf (Re: "Secure coding" audit checkers and Kerberos) In-Reply-To: <1224129303.6796.210.camel@error-messages.mit.edu> (Greg Hudson's message of "Wed, 15 Oct 2008 23:55:03 -0400") References: <200810150106.m9F16QC1004443@outgoing-legacy.mit.edu> <20081016025800.GA8906@Sun.COM> <1224129303.6796.210.camel@error-messages.mit.edu> Message-ID: Greg Hudson writes: > On Wed, 2008-10-15 at 21:58 -0500, Nicolas Williams wrote: >> You use a precision field for %s? Where? > > Not often. Precision fields: > > ./src/kadmin/ktutil/ktutil_funcs.c: sprintf(promptstr, "Password for %.1000s", princ_str); > ./src/kadmin/cli/kadmin.c: sprintf(prompt1, "Enter password for principal \"%.900s\"", > ./src/kadmin/cli/kadmin.c: "Re-enter password for principal \"%.900s\"", > ./src/kadmin/cli/kadmin.c: sprintf(prompt1, "Enter password for principal \"%.900s\"", > ./src/kadmin/cli/kadmin.c: "Re-enter password for principal \"%.900s\"", > > The precision field in those uses can probably be removed if the calls > are switched to use snprintf. > > We use field widths with %s in 33 places, but it's all printf and > fprintf, not sprintf. Mostly in plugins/kdb. We use %.*s (precision specified in an integer argument) in over 100 places, many of them in the libraries. Some of these are debugging code, but some are for things like producing enhanced error message strings. Some of these uses are to compensate for strings in krb5_data or gss_buffer_t, which are not required to have null termination. From raeburn at MIT.EDU Thu Oct 16 09:04:26 2008 From: raeburn at MIT.EDU (Ken Raeburn) Date: Thu, 16 Oct 2008 09:04:26 -0400 Subject: "Secure coding" audit checkers and Kerberos In-Reply-To: <1224149535.28298.90.camel@hopeson> References: <20081015205426.GM8906@Sun.COM> <536.1224104710@malison.ait.iastate.edu> <20081015211618.GP8906@Sun.COM> <20081016030016.GB8906@Sun.COM> <1224149535.28298.90.camel@hopeson> Message-ID: On Oct 16, 2008, at 05:32, Simo Sorce wrote: > After almost 10 years from C99 avoiding it would be just absurd if you > ask me. If there are platforms that really can't cope with C99 after > 10 > years I honestly think nobody should consider using them as a KDC > anyway. Sadly, C99 compliance often isn't complete or default, even now. And the compiler options for enabling C99 compliance sometimes turn off OS extensions; we need some of those extensions, which often require other, additional options. And they're not necessarily something that can easily be tested for automatically. Still, probably the biggest reason we can't start relying on a bunch more C99 stuff in our libraries is the lack of support on Windows. Ken From tlyu at MIT.EDU Thu Oct 16 10:02:39 2008 From: tlyu at MIT.EDU (Tom Yu) Date: Thu, 16 Oct 2008 10:02:39 -0400 Subject: "Secure coding" audit checkers and Kerberos In-Reply-To: (Ken Raeburn's message of "Thu, 16 Oct 2008 09:04:26 -0400") References: <20081015205426.GM8906@Sun.COM> <536.1224104710@malison.ait.iastate.edu> <20081015211618.GP8906@Sun.COM> <20081016030016.GB8906@Sun.COM> <1224149535.28298.90.camel@hopeson> Message-ID: Ken Raeburn writes: > On Oct 16, 2008, at 05:32, Simo Sorce wrote: >> After almost 10 years from C99 avoiding it would be just absurd if you >> ask me. If there are platforms that really can't cope with C99 after >> 10 >> years I honestly think nobody should consider using them as a KDC >> anyway. > > Sadly, C99 compliance often isn't complete or default, even now. And > the compiler options for enabling C99 compliance sometimes turn off OS > extensions; we need some of those extensions, which often require > other, additional options. And they're not necessarily something that > can easily be tested for automatically. Ten years after C89 was published, compiler and library support were incomplete on many platforms. Likewise, almost ten years after C99 was published, compiler and library support for it are incomplete on many platforms. My experience is that compilers become conforming well before libraries do. For this reason can use new freestanding language features before we use new library features. > Still, probably the biggest reason we can't start relying on a bunch > more C99 stuff in our libraries is the lack of support on Windows. Specifically, I recall that the Visual Studio suite still lacks C99 support. From jaltman at secure-endpoints.com Thu Oct 16 10:41:23 2008 From: jaltman at secure-endpoints.com (Jeffrey Altman) Date: Thu, 16 Oct 2008 10:41:23 -0400 Subject: security goals re strcpy/strcat/sprintf (Re: "Secure coding" audit checkers and Kerberos) In-Reply-To: References: <200810150106.m9F16QC1004443@outgoing-legacy.mit.edu> Message-ID: <48F75293.60304@secure-endpoints.com> Please consider that Windows does not support asprintf, strl*, and the format strings for the *printf family differ from those on *nix. Windows of course also supports Unicode (wchar_t) C strings. To address Microsoft has developed the StrSafe library of functions for the manipulation of char_t and wchar_t strings. Quoting http://msdn.microsoft.com/en-us/library/ms647466.aspx : "The advantages of the Strsafe functions include: * The size of the destination buffer is always provided to the function to ensure that the function does not write past the end of the buffer. * Buffers are guaranteed to be null-terminated, even if the operation truncates the intended result. * All functions return an HRESULT, with only one possible success code (S_OK). * Each function is available in a corresponding character count (cch) or byte count (cb) version. * Most functions have an extended ("Ex") version available for advanced functionality." S_OK is 0. Examples of the extended functionality are output pointers to the end of the string, an output size_t value indicating the number of bytes/chars remaining in the buffer, and a input flags parameter permitting various options: STRSAFE_FILL_BEHIND_NULL If the function succeeds, the low byte of dwFlags (0) is used to fill the uninitialized portion of pszDest following the terminating null character. STRSAFE_IGNORE_NULLS Treat null string pointers like empty strings (TEXT("")). STRSAFE_FILL_ON_FAILURE If the function fails, the low byte of dwFlags (0) is used to fill the entire pszDest buffer, and the buffer is null-terminated. In the case of a STRSAFE_E_INSUFFICIENT_BUFFER failure, any truncated string returned is overwritten. STRSAFE_NULL_ON_FAILURE If the function fails, pszDest is set to an empty string (TEXT("")). In the case of a STRSAFE_E_INSUFFICIENT_BUFFER failure, any truncated string is overwritten. STRSAFE_NO_TRUNCATION As in the case of STRSAFE_NULL_ON_FAILURE, if the function fails, pszDest is set to an empty string (TEXT("")). In the case of a STRSAFE_E_INSUFFICIENT_BUFFER failure, any truncated string is overwritten. The interface is well thought out. MIT might consider implementing this interface for *nix and relying on it throughout the code base. Or at the very least implement the functions that are selected for Windows by making use of this interface. Just my two cents .... Jeffrey Altman -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/x-pkcs7-signature Size: 3355 bytes Desc: S/MIME Cryptographic Signature Url : http://mailman.mit.edu/pipermail/krbdev/attachments/20081016/d1aef4d7/smime-0001.bin From Nicolas.Williams at sun.com Thu Oct 16 16:56:49 2008 From: Nicolas.Williams at sun.com (Nicolas Williams) Date: Thu, 16 Oct 2008 15:56:49 -0500 Subject: security goals re strcpy/strcat/sprintf (Re: "Secure coding" audit checkers and Kerberos) In-Reply-To: <48F75293.60304@secure-endpoints.com> References: <200810150106.m9F16QC1004443@outgoing-legacy.mit.edu> <48F75293.60304@secure-endpoints.com> Message-ID: <20081016205648.GT8906@Sun.COM> On Thu, Oct 16, 2008 at 10:41:23AM -0400, Jeffrey Altman wrote: > The interface is well thought out. MIT might consider implementing this > interface for *nix and relying on it throughout the code base. Or at > the very least implement the functions that are selected for Windows by > making use of this interface. StringCbCat() looks very similar to strlcat(), only slightly crippled (it doesn't return a length, but success/failure). StringCbCatEx(), apart from its flags argument, makes up for that limitation. StringCbPrintfEx() provides similar functionality to snprintf(), plus the flags argument. StringCbLength() is like strnlen(). The best thing about these functions may well be that the difference between counting characters and counting bytes is quite explicit. The behavior of str*() and *printf() functions w.r.t. byte-or-char counting might turn out to depend on the phases of the moon and such, and that would be bad. If this is the case for anything beyond *printf() %s precision fields then I will agree with your recommendation that "MIT consider implementing this interface for *nix." Thanks for the pointer to this API! Nico -- From ashutosh.datar at hp.com Fri Oct 17 05:26:52 2008 From: ashutosh.datar at hp.com (Datar, Ashutosh Anil) Date: Fri, 17 Oct 2008 09:26:52 +0000 Subject: Regarding Issues with Memory Credential Cache In-Reply-To: References: <48AEEE48.8010209@mit.edu> Message-ID: Hi Ezra, Did you get to see if the modification to mod_auth_kerb, as you had suggested, works well and gets rid of the segmentation faults in memory cache section? Did you try making any changes to memory cache code? As I said in my last mail, protecting the memory cache list traversal worked very well with mod_auth_kerb and didn't reproduce the SIGSEGV issues further. Thanks and Regards, Ashutosh -----Original Message----- From: krbdev-bounces at mit.edu [mailto:krbdev-bounces at mit.edu] On Behalf Of Datar, Ashutosh Anil Sent: Friday, August 29, 2008 6:29 PM To: Ezra Peisach Cc: krbdev at mit.edu Subject: RE: Regarding Issues with Memory Credential Cache Hi, Thanks very much for your analysis and feedback on the issue. I will also try to test with the suggested changes in mod_auth_kerb code and see how it works. About the other point of changing memory cache code of Kerberos client, I have already tried protecting the memory cache list traversal which will prevent initialization of cache doing something illegal while someone else is still accessing it. It worked well with mod_auth_kerb under high load and I didn't see any SIGSEGVs after that. Thanks again for the feedback. Regards, Ashutosh -----Original Message----- From: Ezra Peisach [mailto:epeisach at MIT.EDU] Sent: Friday, August 22, 2008 10:20 PM To: Datar, Ashutosh Anil Cc: krbdev at mit.edu Subject: Re: Regarding Issues with Memory Credential Cache Datar, Ashutosh Anil wrote: > Hi, > > I was testing Apache Web Server (which uses mod_auth_kerb) with > Kerberos Client 1.6.2 and found some issue with the Memory Cache handling. Okay - I have examined the situation a little more. The problem is readlly with mod_auth_kerb. In version 5.3 (released at the end of 2006) - krb5_cc_resolve is used to create a temporary memory cache in two places. The second argument for the cache is "MEMORY:". This indicates that we want a memory cache with name "". The cache is initialized, used and destroyed - so I believe it was never intended to last. So - another thread might be iterating through the same cache and another thread then nukes the contents of the cache with krb5_cc_initialize. The fix is pretty easy - in mod_auth_kerb, there are two places krb5_cc_resolve is used with "MEMORY:" as the second argument. Change the code to use krb5_cc_new_unique and that should solve your problem.... (the type should be "MEMORY" without the :) I would make the change the mod_auth_kerb and if it works - send the fix to the author. I will meanwhile devise a way to bullet proof the memory cache code - to at least ensure that initializing a cache while someone else is walking it - will not do anything illegal - but probably result in an emptied cache - which is not what mod_auth_kerb would be expecting... Ezra _______________________________________________ krbdev mailing list krbdev at mit.edu https://mailman.mit.edu/mailman/listinfo/krbdev From kouril at ics.muni.cz Fri Oct 17 08:57:40 2008 From: kouril at ics.muni.cz (Daniel Kouril) Date: Fri, 17 Oct 2008 14:57:40 +0200 Subject: Regarding Issues with Memory Credential Cache In-Reply-To: References: <48AEEE48.8010209@mit.edu> Message-ID: <20081017125740.GK67351@w54-188.fi.muni.cz> For completness sake note that the change has been applied as revision 1.143 of the mod_auth_kerb.c source: http://modauthkerb.cvs.sourceforge.net/viewvc/modauthkerb/mod_auth_kerb/src/mod_auth_kerb.c?r1=1.141&r2=1.142 The original module bug report can be found at http://sourceforge.net/tracker/index.php?func=detail&aid=1971514&group_id=51775&atid=464524 we'd be gratefull for any overview of the change, cheers, Daniel On Fri, Oct 17, 2008 at 09:26:52AM +0000, Datar, Ashutosh Anil wrote: > Hi Ezra, > > Did you get to see if the modification to mod_auth_kerb, as you had suggested, works well and gets rid of the segmentation faults in memory cache section? > Did you try making any changes to memory cache code? > > As I said in my last mail, protecting the memory cache list traversal worked very well with mod_auth_kerb and didn't reproduce the SIGSEGV issues further. > > Thanks and Regards, > Ashutosh > > -----Original Message----- > From: krbdev-bounces at mit.edu [mailto:krbdev-bounces at mit.edu] On Behalf Of Datar, Ashutosh Anil > Sent: Friday, August 29, 2008 6:29 PM > To: Ezra Peisach > Cc: krbdev at mit.edu > Subject: RE: Regarding Issues with Memory Credential Cache > > Hi, > > Thanks very much for your analysis and feedback on the issue. > I will also try to test with the suggested changes in mod_auth_kerb code and see how it works. > > About the other point of changing memory cache code of Kerberos client, > I have already tried protecting the memory cache list traversal which will prevent initialization of cache doing something illegal while someone else is still accessing it. It worked well with mod_auth_kerb under high load and I didn't see any SIGSEGVs after that. > > Thanks again for the feedback. > > Regards, > Ashutosh > > -----Original Message----- > From: Ezra Peisach [mailto:epeisach at MIT.EDU] > Sent: Friday, August 22, 2008 10:20 PM > To: Datar, Ashutosh Anil > Cc: krbdev at mit.edu > Subject: Re: Regarding Issues with Memory Credential Cache > > Datar, Ashutosh Anil wrote: > > Hi, > > > > I was testing Apache Web Server (which uses mod_auth_kerb) with > > Kerberos Client 1.6.2 and found some issue with the Memory Cache handling. > > Okay - I have examined the situation a little more. The problem is > readlly with mod_auth_kerb. In version 5.3 (released at the end of > 2006) - krb5_cc_resolve is used to create a temporary > memory cache in two places. > > The second argument for the cache is "MEMORY:". This indicates that we > want a memory cache with name "". The cache is initialized, used and > destroyed - so I believe it was never intended to last. So - another > thread might be iterating through the same cache and another thread then > nukes the contents of the cache with krb5_cc_initialize. > > The fix is pretty easy - in mod_auth_kerb, there are two places > krb5_cc_resolve is used with "MEMORY:" as the second argument. Change > the code to use krb5_cc_new_unique and that should solve your > problem.... (the type should be "MEMORY" without the :) > > I would make the change the mod_auth_kerb and if it works - send the fix > to the author. > > I will meanwhile devise a way to bullet proof the memory cache code - to > at least ensure that initializing a cache while someone else is walking > it - will not do anything illegal - but probably result in an emptied > cache - which is not what mod_auth_kerb would be expecting... > > Ezra > > > _______________________________________________ > krbdev mailing list krbdev at mit.edu > https://mailman.mit.edu/mailman/listinfo/krbdev > > _______________________________________________ > krbdev mailing list krbdev at mit.edu > https://mailman.mit.edu/mailman/listinfo/krbdev From William.Fiveash at Sun.COM Fri Oct 17 15:40:45 2008 From: William.Fiveash at Sun.COM (Will Fiveash) Date: Fri, 17 Oct 2008 14:40:45 -0500 Subject: questions about entry->mkvno logic in kadm5_get_principal() Message-ID: <20081017194044.GA14825@sun.com> In src/lib/kadm5/srv/svr_principal.c:kadm5_get_principal() there is this logic: if (handle->api_version == KADM5_API_VERSION_2) entry->mkvno = 0; else { /* XXX I'll be damned if I know how to deal with this one --marc */ entry->mkvno = 1; } Any idea as to why mkvno differs depending on the KADM5_API_VERSION? I'm also wondering if that logic is correct if KADM5_API_VERSION is incremented (so mkvno should be 1?). I'm asking this because I'm modifying the code at this point to look up the mkvno in the entry's new KRB5_TL_MKVNO tl_data but if that doesn't exist then mkvno will be assigned a fall back default value and I want to make sure it's the correct value. -- Will Fiveash Sun Microsystems Inc. http://opensolaris.org/os/project/kerberos/ From since at opendemand.com Sun Oct 19 16:23:45 2008 From: since at opendemand.com (Stephen Ince) Date: Sun, 19 Oct 2008 16:23:45 -0400 Subject: gss_init_sec_context error for spnego References: <20081015205426.GM8906@Sun.COM><536.1224104710@malison.ait.iastate.edu><20081015211618.GP8906@Sun.COM> <54b301c92f10$d25b97d0$6e00a8c0@desktop2> Message-ID: <607001c93228$962222f0$6e00a8c0@desktop2> I am getting a 589824 major status for gss_init_sec_context. Does any know why? It is for the second call to gss_init_sec_context. Basically I am doing the following. major_status = gss_init_sec_context(&minor_status, GSS_C_NO_CREDENTIAL, &neg_ctx->context, neg_ctx->server_name, &gss_spnego_mech_oid_desc, GSS_C_MUTUAL_FLAG|GSS_C_DELEG_FLAG|GSS_C_REPLAY_FLAG , GSS_C_INDEFINITE, GSS_C_NO_CHANNEL_BINDINGS, &input_token, NULL, &output_token, NULL, NULL); On the first call to gss_init_sec_context the variable neg_ctx->context is intialized to GSS_C_NO_CONTEXT I fail on the second call to gss_init_sec_context Steve since at opendemand.com From since at opendemand.com Mon Oct 20 00:37:33 2008 From: since at opendemand.com (Stephen Ince) Date: Mon, 20 Oct 2008 00:37:33 -0400 Subject: gss_init_sec_context error for spnego References: <20081015205426.GM8906@Sun.COM><536.1224104710@malison.ait.iastate.edu><20081015211618.GP8906@Sun.COM><54b301c92f10$d25b97d0$6e00a8c0@desktop2> <607001c93228$962222f0$6e00a8c0@desktop2> Message-ID: <61b301c9326d$a6ca2720$6e00a8c0@desktop2> I have made some progress. I am now getting a "Message stream modified" from gss_init_sec_context on the second call. I am doing the following. gss_krb5_ccache_name gss_init_sec_context get and decode input negotiate from IE gss_init_sec_context I think my error maybe how I am base64 decoding the negotiate token. or in how I am setting the default creditial cache. Any help would be greatly appreciated. Steve ----- Original Message ----- From: "Stephen Ince" To: Sent: Sunday, October 19, 2008 4:23 PM Subject: gss_init_sec_context error for spnego >I am getting a 589824 major status for gss_init_sec_context. Does any know > why? It is for the second call to gss_init_sec_context. > > Basically I am doing the following. > > major_status = gss_init_sec_context(&minor_status, > GSS_C_NO_CREDENTIAL, > &neg_ctx->context, > neg_ctx->server_name, > &gss_spnego_mech_oid_desc, > GSS_C_MUTUAL_FLAG|GSS_C_DELEG_FLAG|GSS_C_REPLAY_FLAG , > GSS_C_INDEFINITE, > GSS_C_NO_CHANNEL_BINDINGS, > &input_token, > NULL, > &output_token, > NULL, > NULL); > > On the first call to gss_init_sec_context the variable neg_ctx->context is > intialized to GSS_C_NO_CONTEXT > I fail on the second call to gss_init_sec_context > > > Steve > since at opendemand.com > > _______________________________________________ > krbdev mailing list krbdev at mit.edu > https://mailman.mit.edu/mailman/listinfo/krbdev > From ashutosh.datar at hp.com Mon Oct 20 05:34:17 2008 From: ashutosh.datar at hp.com (Datar, Ashutosh Anil) Date: Mon, 20 Oct 2008 09:34:17 +0000 Subject: Query regarding the ticket options passed set an application Message-ID: Hi, I had a query regarding the treatment given to options ("forwardable" or "proxiable") passed by an application through the call krb5_get_in_tkt_with_password (). What we observed while working on PAM Kerberos (libpam_krb5) is that, if an option is not mentioned by the PAM configuration file, then the mentioned function (krb5_get_in_tkt_with_password) sets it to "false". Now that the option is set to something, the libdefault value for that option won't be considered at all. Because, the code in function krb5_get_init_creds () checks to see if the option is already set (to something, be it false or true) and if set, then takes the previously specified value. This makes a difference when no option is specified in PAM but the same option is set to true in Kerberos configuration; because in this case, the Kerberos option will be totally ignored. ==================================================================== Options are set in krb5int_populate_gic_opt () like: : if (options&KDC_OPT_FORWARDABLE) krb5_get_init_creds_opt_set_forwardable(opt, 1); else krb5_get_init_creds_opt_set_forwardable(opt, 0); if (options&KDC_OPT_PROXIABLE) krb5_get_init_creds_opt_set_proxiable(opt, 1); else krb5_get_init_creds_opt_set_proxiable(opt, 0); : Functions krb5_get_init_creds sets the options as follows: if (options && (options->flags & KRB5_GET_INIT_CREDS_OPT_FORWARDABLE)) tempint = options->forwardable; else if ((ret = krb5_libdefault_boolean(context, &client->realm, "forwardable", &tempint)) == 0) ; else tempint = 0; if (tempint) request.kdc_options |= KDC_OPT_FORWARDABLE; ==================================================================== Now the question is if there is any specific reason behind keeping it like this? Because, the "libdefaults" in krb5.conf being the default options for libkrb5 library, an application can override them but in case an application doesn't mention about the option, it can always refer to the default value set for that option in Kerberos configuration. Also, the default values of these options being "false", if none of the configurations (application and Kerberos) are mentioning about an option, it will not affect the application logic also. While searching online, I could see few of the other implementations, where the specific options from application configuration (PAM here) take preference but otherwise the defaults from krb5.conf will always be considered. Can you please let me know if this is the expected behavior and if yes, why? Thanks and Regards, Ashutosh From tlyu at MIT.EDU Mon Oct 20 09:58:44 2008 From: tlyu at MIT.EDU (Tom Yu) Date: Mon, 20 Oct 2008 09:58:44 -0400 Subject: questions about entry->mkvno logic in kadm5_get_principal() In-Reply-To: <20081017194044.GA14825@sun.com> (Will Fiveash's message of "Fri, 17 Oct 2008 14:40:45 -0500") References: <20081017194044.GA14825@sun.com> Message-ID: Will Fiveash writes: > In src/lib/kadm5/srv/svr_principal.c:kadm5_get_principal() > there is this logic: > > if (handle->api_version == KADM5_API_VERSION_2) > entry->mkvno = 0; > else { > /* XXX I'll be damned if I know how to deal with this one --marc */ > entry->mkvno = 1; > } > > Any idea as to why mkvno differs depending on the KADM5_API_VERSION? > I'm also wondering if that logic is correct if KADM5_API_VERSION is > incremented (so mkvno should be 1?). I have no idea why it's different. API version 1 is for compatibility with the OpenVison admin system. I suspect that nobody cares about that anymore. > I'm asking this because I'm modifying the code at this point to look up > the mkvno in the entry's new KRB5_TL_MKVNO tl_data but if that doesn't > exist then mkvno will be assigned a fall back default value and I want > to make sure it's the correct value. If you feel like duplicating the logic, I suspect that's fine. From simon at josefsson.org Mon Oct 20 08:16:35 2008 From: simon at josefsson.org (Simon Josefsson) Date: Mon, 20 Oct 2008 14:16:35 +0200 Subject: gss_init_sec_context error for spnego In-Reply-To: <607001c93228$962222f0$6e00a8c0@desktop2> (Stephen Ince's message of "Sun, 19 Oct 2008 16:23:45 -0400") References: <20081015205426.GM8906@Sun.COM> <536.1224104710@malison.ait.iastate.edu> <20081015211618.GP8906@Sun.COM> <54b301c92f10$d25b97d0$6e00a8c0@desktop2> <607001c93228$962222f0$6e00a8c0@desktop2> Message-ID: <87abczqx5o.fsf@mocca.josefsson.org> "Stephen Ince" writes: > I am getting a 589824 major status for gss_init_sec_context. Does any know > why? It is for the second call to gss_init_sec_context. > > Basically I am doing the following. > > major_status = gss_init_sec_context(&minor_status, > GSS_C_NO_CREDENTIAL, > &neg_ctx->context, > neg_ctx->server_name, > &gss_spnego_mech_oid_desc, > GSS_C_MUTUAL_FLAG|GSS_C_DELEG_FLAG|GSS_C_REPLAY_FLAG , > GSS_C_INDEFINITE, > GSS_C_NO_CHANNEL_BINDINGS, > &input_token, > NULL, > &output_token, > NULL, > NULL); > > On the first call to gss_init_sec_context the variable neg_ctx->context is > intialized to GSS_C_NO_CONTEXT > I fail on the second call to gss_init_sec_context Did you check error code on the first gss_init_sec_context? Maybe it didn't work. /Simon jas at mocca:~$ gss -m 589824 GSS-API major status code 589824 (0x90000). MSB LSB +-----------------+-----------------+---------------------------------+ | Calling Error | Routine Error | Supplementary Info | | 0 0 0 0 0 0 0 0 | 0 0 0 0 1 0 0 1 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 | +-----------------+-----------------+---------------------------------+ Bit 31 24 23 16 15 0 Masked routine error 589824 (0x90000) shifted into 9 (0x9): A token was invalid jas at mocca:~$ From tlyu at MIT.EDU Mon Oct 20 10:28:00 2008 From: tlyu at MIT.EDU (Tom Yu) Date: Mon, 20 Oct 2008 10:28:00 -0400 Subject: gss_init_sec_context error for spnego In-Reply-To: <61b301c9326d$a6ca2720$6e00a8c0@desktop2> (Stephen Ince's message of "Mon, 20 Oct 2008 00:37:33 -0400") References: <20081015205426.GM8906@Sun.COM> <536.1224104710@malison.ait.iastate.edu> <20081015211618.GP8906@Sun.COM> <54b301c92f10$d25b97d0$6e00a8c0@desktop2> <607001c93228$962222f0$6e00a8c0@desktop2> <61b301c9326d$a6ca2720$6e00a8c0@desktop2> Message-ID: "Stephen Ince" writes: > I have made some progress. I am now getting a "Message stream modified" > from gss_init_sec_context on the second call. > > I am doing the following. > > gss_krb5_ccache_name > gss_init_sec_context > > get and decode input negotiate from IE > gss_init_sec_context > > > I think my error maybe how I am base64 decoding the negotiate token. or in > how I am setting the default creditial cache. > Any help would be greatly appreciated. It would help to know a few more details about what you are trying to do. For example, what software is acting as the GSS acceptor? Your "get and decode input negotiate from IE" suggests that you are trying to act as a web server reading GSS tokens from an IE browser, in which case you are acting as acceptor, not initiator. From since at opendemand.com Mon Oct 20 16:33:06 2008 From: since at opendemand.com (Stephen Ince) Date: Mon, 20 Oct 2008 16:33:06 -0400 Subject: gss_init_sec_context error for spnego References: <20081015205426.GM8906@Sun.COM><536.1224104710@malison.ait.iastate.edu><20081015211618.GP8906@Sun.COM><54b301c92f10$d25b97d0$6e00a8c0@desktop2><607001c93228$962222f0$6e00a8c0@desktop2><87abczqx5o.fsf@mocca.josefsson.org><621a01c932c0$10671330$6e00a8c0@desktop2> <878wsjpbl9.fsf@mocca.josefsson.org> Message-ID: <62b901c932f3$11146200$6e00a8c0@desktop2> Simon. Thx for the advice. I am going to switch back to apache to verify that the input_token is correct. I can do more tracing through apache than IIS. I did read in the Mozilla code that their base64 decode was not that robust as IE. I am not using the same routine but the problem could be the same. int decode_len = apr_base64_decode_len(header); input_token.value = (char*)malloc(decode_len +1); input_token.length = apr_base64_decode(input_token.value,header); Steve ----- Original Message ----- From: "Simon Josefsson" To: "Stephen Ince" Sent: Monday, October 20, 2008 10:47 AM Subject: Re: gss_init_sec_context error for spnego > Stephen, I don't know how to debug it further -- the error message > indicates that the token is invalid. So either the code generating it > is buggy, or the code that parses it is buggy, or (and definitely most > likely) your code that passes the token between the generator and parser > is buggy and corrupts the token somehow. > > Are you sure 'input_token' is initialized properly with the token data? > > /Simon > > "Stephen Ince" writes: > >> Simon, >> Thx for your response. >> I do check for error_status. I think IIS is ignoring the req_flags >> and maybe encypting. When I had the req_flags set 0. It still returns >> GSS_S_CONTINUE_NEEDED. Is there anyway I can if I need to unwrap the >> token. >> >> major_status = gss_init_sec_context(&minor_status, >> if (major_status == GSS_S_COMPLETE) { >> } >> else if (major_status == GSS_S_CONTINUE_NEEDED) { >> } >> >> if (GSS_ERROR(major_status)) { >> /* Curl_cleanup_negotiate(conn->data) ??? */ >> log_gss_error(major_status,minor_status,"gss_init_sec_context() >> failed: "); >> return APR_EGENERAL; >> } >> >> ----- Original Message ----- >> From: "Simon Josefsson" >> To: "Stephen Ince" >> Cc: >> Sent: Monday, October 20, 2008 8:16 AM >> Subject: Re: gss_init_sec_context error for spnego >> >> >>> "Stephen Ince" writes: >>> >>>> I am getting a 589824 major status for gss_init_sec_context. Does >>>> any know >>>> why? It is for the second call to gss_init_sec_context. >>>> >>>> Basically I am doing the following. >>>> >>>> major_status = gss_init_sec_context(&minor_status, >>>> GSS_C_NO_CREDENTIAL, >>>> &neg_ctx->context, >>>> neg_ctx->server_name, >>>> &gss_spnego_mech_oid_desc, >>>> GSS_C_MUTUAL_FLAG|GSS_C_DELEG_FLAG|GSS_C_REPLAY_FLAG , >>>> GSS_C_INDEFINITE, >>>> GSS_C_NO_CHANNEL_BINDINGS, >>>> &input_token, >>>> NULL, >>>> &output_token, >>>> NULL, >>>> NULL); >>>> >>>> On the first call to gss_init_sec_context the variable >>>> neg_ctx->context is >>>> intialized to GSS_C_NO_CONTEXT >>>> I fail on the second call to gss_init_sec_context >>> >>> Did you check error code on the first gss_init_sec_context? Maybe it >>> didn't work. >>> >>> /Simon >>> >>> jas at mocca:~$ gss -m 589824 >>> GSS-API major status code 589824 (0x90000). >>> >>> MSB >>> LSB >>> >>> +-----------------+-----------------+---------------------------------+ >>> | Calling Error | Routine Error | Supplementary Info >>> | >>> | 0 0 0 0 0 0 0 0 | 0 0 0 0 1 0 0 1 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 >>> | >>> >>> +-----------------+-----------------+---------------------------------+ >>> Bit 31 24 23 16 15 0 >>> >>> Masked routine error 589824 (0x90000) shifted into 9 (0x9): >>> A token was invalid >>> >>> jas at mocca:~$ >>> > From since at opendemand.com Mon Oct 20 16:57:53 2008 From: since at opendemand.com (Stephen Ince) Date: Mon, 20 Oct 2008 16:57:53 -0400 Subject: gss_init_sec_context error for spnego References: <20081015205426.GM8906@Sun.COM><536.1224104710@malison.ait.iastate.edu><20081015211618.GP8906@Sun.COM><54b301c92f10$d25b97d0$6e00a8c0@desktop2><607001c93228$962222f0$6e00a8c0@desktop2><87abczqx5o.fsf@mocca.josefsson.org><621a01c932c0$10671330$6e00a8c0@desktop2><878wsjpbl9.fsf@mocca.josefsson.org> <62b901c932f3$11146200$6e00a8c0@desktop2> Message-ID: <62f301c932f6$85a8b6e0$6e00a8c0@desktop2> I think my hunch was correct, IIS is ignoring the req_flags. Everything worked when I tested apache. The format of the token coming back from IIS must be encrypted. I did an ethereal snoop and noticed that gss_init_sec_context fails and does not make any network calls. Is there a way I can check for the format of the IIS token from the first gss_init_sec_context? I do not tell IIS to encrypt the token. e.g. req_flags= GSS_C_MUTUAL_FLAG|GSS_C_DELEG_FLAG|GSS_C_REPLAY_FLAG gss_init_sec_context check the ret_flags if the token from IIS will be encrypted? get and decode input negotiate from IE and decrypt or unwrap token gss_init_sec_context Steve ----- Original Message ----- From: "Stephen Ince" To: Sent: Monday, October 20, 2008 4:33 PM Subject: Re: gss_init_sec_context error for spnego > Simon. > Thx for the advice. I am going to switch back to apache to verify that > the input_token is correct. I can do more tracing through apache than IIS. > I did read in the Mozilla code that their base64 decode was not that > robust > as IE. I am not using the same routine but the problem could be the same. > > int decode_len = apr_base64_decode_len(header); > input_token.value = (char*)malloc(decode_len +1); > input_token.length = apr_base64_decode(input_token.value,header); > > Steve > ----- Original Message ----- > From: "Simon Josefsson" > To: "Stephen Ince" > Sent: Monday, October 20, 2008 10:47 AM > Subject: Re: gss_init_sec_context error for spnego > > >> Stephen, I don't know how to debug it further -- the error message >> indicates that the token is invalid. So either the code generating it >> is buggy, or the code that parses it is buggy, or (and definitely most >> likely) your code that passes the token between the generator and parser >> is buggy and corrupts the token somehow. >> >> Are you sure 'input_token' is initialized properly with the token data? >> >> /Simon >> >> "Stephen Ince" writes: >> >>> Simon, >>> Thx for your response. >>> I do check for error_status. I think IIS is ignoring the req_flags >>> and maybe encypting. When I had the req_flags set 0. It still returns >>> GSS_S_CONTINUE_NEEDED. Is there anyway I can if I need to unwrap the >>> token. >>> >>> major_status = gss_init_sec_context(&minor_status, >>> if (major_status == GSS_S_COMPLETE) { >>> } >>> else if (major_status == GSS_S_CONTINUE_NEEDED) { >>> } >>> >>> if (GSS_ERROR(major_status)) { >>> /* Curl_cleanup_negotiate(conn->data) ??? */ >>> log_gss_error(major_status,minor_status,"gss_init_sec_context() >>> failed: "); >>> return APR_EGENERAL; >>> } >>> >>> ----- Original Message ----- >>> From: "Simon Josefsson" >>> To: "Stephen Ince" >>> Cc: >>> Sent: Monday, October 20, 2008 8:16 AM >>> Subject: Re: gss_init_sec_context error for spnego >>> >>> >>>> "Stephen Ince" writes: >>>> >>>>> I am getting a 589824 major status for gss_init_sec_context. Does >>>>> any know >>>>> why? It is for the second call to gss_init_sec_context. >>>>> >>>>> Basically I am doing the following. >>>>> >>>>> major_status = gss_init_sec_context(&minor_status, >>>>> GSS_C_NO_CREDENTIAL, >>>>> &neg_ctx->context, >>>>> neg_ctx->server_name, >>>>> &gss_spnego_mech_oid_desc, >>>>> GSS_C_MUTUAL_FLAG|GSS_C_DELEG_FLAG|GSS_C_REPLAY_FLAG , >>>>> GSS_C_INDEFINITE, >>>>> GSS_C_NO_CHANNEL_BINDINGS, >>>>> &input_token, >>>>> NULL, >>>>> &output_token, >>>>> NULL, >>>>> NULL); >>>>> >>>>> On the first call to gss_init_sec_context the variable >>>>> neg_ctx->context is >>>>> intialized to GSS_C_NO_CONTEXT >>>>> I fail on the second call to gss_init_sec_context >>>> >>>> Did you check error code on the first gss_init_sec_context? Maybe it >>>> didn't work. >>>> >>>> /Simon >>>> >>>> jas at mocca:~$ gss -m 589824 >>>> GSS-API major status code 589824 (0x90000). >>>> >>>> MSB >>>> LSB >>>> >>>> +-----------------+-----------------+---------------------------------+ >>>> | Calling Error | Routine Error | Supplementary Info >>>> | >>>> | 0 0 0 0 0 0 0 0 | 0 0 0 0 1 0 0 1 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 >>>> | >>>> >>>> +-----------------+-----------------+---------------------------------+ >>>> Bit 31 24 23 16 15 >>>> 0 >>>> >>>> Masked routine error 589824 (0x90000) shifted into 9 (0x9): >>>> A token was invalid >>>> >>>> jas at mocca:~$ >>>> >> > > _______________________________________________ > krbdev mailing list krbdev at mit.edu > https://mailman.mit.edu/mailman/listinfo/krbdev > From raeburn at MIT.EDU Mon Oct 20 17:16:47 2008 From: raeburn at MIT.EDU (Ken Raeburn) Date: Mon, 20 Oct 2008 17:16:47 -0400 Subject: gss_init_sec_context error for spnego In-Reply-To: <62f301c932f6$85a8b6e0$6e00a8c0@desktop2> References: <20081015205426.GM8906@Sun.COM><536.1224104710@malison.ait.iastate.edu><20081015211618.GP8906@Sun.COM><54b301c92f10$d25b97d0$6e00a8c0@desktop2><607001c93228$962222f0$6e00a8c0@desktop2><87abczqx5o.fsf@mocca.josefsson.org><621a01c932c0$10671330$6e00a8c0@desktop2><878wsjpbl9.fsf@mocca.josefsson.org> <62b901c932f3$11146200$6e00a8c0@desktop2> <62f301c932f6$85a8b6e0$6e00a8c0@desktop2> Message-ID: On Oct 20, 2008, at 16:57, Stephen Ince wrote: > I think my hunch was correct, IIS is ignoring the req_flags. > Everything > worked when I tested apache. The format of the token coming back > from IIS > must be encrypted. I did an ethereal snoop and noticed that > gss_init_sec_context fails and does not make any network calls. > Is there a way I can check for the format of the IIS token from the > first > gss_init_sec_context? I do not tell IIS to encrypt the token. Right, gss_init_sec_context doesn't talk to the server. It forms messages for you to send -- depending on your application protocol, perhaps base-64 encoded, perhaps with some wrapper text, etc -- and then (for the next call) you give it a message you got back from the server. If you're using Kerberos, it *may* use the network to talk to the KDC, but if you already have local credentials, it may not need to. As Tom indicated earlier, it's not really clear from your messages what you're doing -- whether the code you're working on is even on the client or server side and what software you're talking to. Are you talking to Apache/IIS over the net with web client code you're modifying, or is your software plugging in to the server and getting contacted with IE? Ken From tlyu at MIT.EDU Mon Oct 20 18:44:40 2008 From: tlyu at MIT.EDU (Tom Yu) Date: Mon, 20 Oct 2008 18:44:40 -0400 Subject: policy on supported platforms References: <87hc7m1xhh.fsf@windlord.stanford.edu> Message-ID: Russ Allbery writes: > Tom Yu writes: > >> I have created a K5Wiki page documenting our policy on supported >> platforms for MIT Kerberos. You may find it at: >> >> http://k5wiki.kerberos.org/wiki/Supported_platforms >> >> We have informally talked about the concept of supported platforms in >> the past; this article attempts to formally set some expectations >> based on historical practice. Please note the section on "Extent of >> support", which defines the expectations we are establishing. > > It's a little ambiguous whether when you say you support Linux, you mean > all Linux architectures or only the ones listed in parentheses > afterwards. None of the parenthesized platform lists specifically mention > x86_64, which is probably an oversight. Thanks for the comments. By x86 we mean to include x86_64, as most of our current Intel hardware falls in that category. I can reword things to more accurately reflect that. By "Linux" we mean Linux-based operating systems as a family of platforms, roughly those which are similar to Debian, Ubuntu, or Red Hat. > Debian currently auto-builds all packages on the following architectures: > > alpha amd64 arm armel hppa i386 ia64 m68k mips mipsel powerpc s390 > sparc > > although arm and m68k are on their way out as first-class platforms. I > expect that few MIT Kerberos features will be sensitive to the > architecture difference given that the same glibc and compilers are used > uniformly. I hope that there would be very few CPU-architecture dependencies. On a supported platform, we would give such issues greater attention than we would on unsupported platforms. > If there are any such sensitivities, it would be good to iron them out, > not at the level of a first-class supported platform but maybe something a > bit better than "a platform-specific problem reported on an unsupported > platform will get preemptively closed unless accompanied by a very > well-written patch that poses negligible integration cost for us." But > generally we can provide help from the Debian side on detailed error > messages and debugging, and I doubt this will be much of an issue in > practice. On a supported operating system, we would devote more resources to dealing with CPU-architecture sensitivities than we would on unsupported operating systems. I agree that on a modern operating system, particularly those that strive for high portability, sensitivities to specific CPU architectures should be minimal and we should try to resolve them. From since at opendemand.com Mon Oct 20 20:00:36 2008 From: since at opendemand.com (Stephen Ince) Date: Mon, 20 Oct 2008 20:00:36 -0400 Subject: gss_init_sec_context error for spnego References: <20081015205426.GM8906@Sun.COM><536.1224104710@malison.ait.iastate.edu><20081015211618.GP8906@Sun.COM><54b301c92f10$d25b97d0$6e00a8c0@desktop2><607001c93228$962222f0$6e00a8c0@desktop2><87abczqx5o.fsf@mocca.josefsson.org><621a01c932c0$10671330$6e00a8c0@desktop2><878wsjpbl9.fsf@mocca.josefsson.org> <62b901c932f3$11146200$6e00a8c0@desktop2> <62f301c932f6$85a8b6e0$6e00a8c0@desktop2> Message-ID: <635a01c93310$cb23e3b0$6e00a8c0@desktop2> Ken, It is a http client. I am try to add kerberos negotiate(spnego) support for our http client. I am using mit kfw libraries on win32. I noticed that mozilla uses sspi on win32 but I don't think this is necessary. I just would like to use one kerberos package. I have the authentication working for apache/mit KDC server, but not for IIS/AD server. Is it the AD that is messing up? req_flags= GSS_C_MUTUAL_FLAG|GSS_C_DELEG_FLAG|GSS_C_REPLAY_FLAG gss_init_sec_context // using the network //check the ret_flags, if the token from IIS will be encrypted? // use http to get to input token from IIS. int decode_len = apr_base64_decode_len(header); input_token.value = (char*)malloc(decode_len +1); input_token.length = apr_base64_decode(input_token.value,header); gss_init_sec_context // set the input_token, this fails for IIS but not for Apache // I get a "Message stream modified" error Steve ----- Original Message ----- From: "Ken Raeburn" To: "Stephen Ince" Cc: Sent: Monday, October 20, 2008 5:16 PM Subject: Re: gss_init_sec_context error for spnego > On Oct 20, 2008, at 16:57, Stephen Ince wrote: >> I think my hunch was correct, IIS is ignoring the req_flags. Everything >> worked when I tested apache. The format of the token coming back from >> IIS >> must be encrypted. I did an ethereal snoop and noticed that >> gss_init_sec_context fails and does not make any network calls. >> Is there a way I can check for the format of the IIS token from the >> first >> gss_init_sec_context? I do not tell IIS to encrypt the token. > > Right, gss_init_sec_context doesn't talk to the server. It forms > messages for you to send -- depending on your application protocol, > perhaps base-64 encoded, perhaps with some wrapper text, etc -- and then > (for the next call) you give it a message you got back from the server. > If you're using Kerberos, it *may* use the network to talk to the KDC, > but if you already have local credentials, it may not need to. > > As Tom indicated earlier, it's not really clear from your messages what > you're doing -- whether the code you're working on is even on the client > or server side and what software you're talking to. Are you talking to > Apache/IIS over the net with web client code you're modifying, or is your > software plugging in to the server and getting contacted with IE? > > Ken > From raeburn at MIT.EDU Tue Oct 21 19:10:20 2008 From: raeburn at MIT.EDU (Ken Raeburn) Date: Tue, 21 Oct 2008 19:10:20 -0400 Subject: ASN.1 encoding in MIT Kerberos Message-ID: Hi. I've been working a bit lately on reworking the ASN.1 encoders in the MIT Kerberos code. I'm hoping to have something ready to put into the source tree soon, probably in the next couple of weeks, so I thought I'd send out a note describing what I'm doing and see if anyone has comments. First: Yes, we know our ASN.1 encoders are ugly and hard to deal with, and in the long term, we should replace them. But using ASN.1 compilers generally involves using new data structures generated by the tools, and since many of our current data structures are exposed in our API, that means either translating at run time, including additional allocations, to convert between different representations, or banging on the generated code from the compiler (or the compiler itself) until it can work with our existing data structures. So in the *short* term, we're trying to come up with something that's both a bit more comprehensible, and a bit more structured so as to reduce the opportunities for errors in writing support for new message types. If it winds up being more compact than our current encoders, so much the better. The short-term project is what I've been working on -- a mostly table- driven encoder targeted primarily at the Kerberos protocol. It only encodes DER, doesn't have many of the primitive ASN.1 types that we don't use, is optimized for sequences where field elements are usually tagged, doesn't handle arbitrarily large tag values, etc. It's not intended to be a fully-functional general-purpose ASN.1 encoder at this stage. I'm also not tackling the decoders at this time. Doing the encoders gets us tables describing the ASN.1 and C data structures to a large degree, and perhaps this can be a starting point for future work on the decoders, but reworking the encoders is a more manageable initial step. ------ Since we don't have a unique mapping in either direction between ASN.1 types and C types, each object we describe is a combination of a C type and an ASN.1 encoding for it; krb5_data encoded as OCTET STRING is different from krb5_data encoded as GeneralString. Each of these gets a "descriptor" name associated with it when we define it. The current revision still works entirely in C code, using helper macros, but I hope they'll be at least somewhat clearer than the existing pile of macros. Two sets of macros are defined. The first set is for defining a C/ASN. 1 type descriptor. You supply a descriptor name and other parameters, such as the C type, or info on sequence fields, or a primitive encoding function. For example: DEFFNTYPE(gstring_data, krb5_data, asn1_encode_generalstring_data_at); DEFPTRTYPE(gstring_data_ptr,gstring_data); Here "gstring_data" becomes a descriptor name for a GeneralString encoded from a krb5_data structure using the indicated function, which takes as one of its arguments a pointer to the krb5_data. If your data structure includes a krb5_data that you want encoded as a GeneralString, you use "gstring_data" to describe it; if it contains a krb5_data*, you would use "gstring_data_ptr", which is defined as encoding the same thing as "gstring_data" but starting with an additional level of indirection. There are also macros for defining descriptors for SEQUENCE types, SEQUENCE OF defined as a null- terminated array of pointers to a base type, an encoding of another type with an APPLICATION tag added, etc. The various DEF*TYPE macros always define a variable type_ that encodes the information about the type -- size, how to encode it, etc. They also define typedefnames associated with the descriptor name so that, for example, when describing a structure field using a descriptor name, we can inject some compile-time code to verify that the structure field has the C type indicated by the descriptor. (Currently that works by creating a "?:" expression using pointers to the expected type and the actual field, so if there's a mismatch, you get a warning or error, but it may refer to a conditional operator you never typed in, so unfortunately it can be a little obscure.) The second set of macros defines fields of a sequence/structure. "Normal" fields are indicated by the C field name and a descriptor describing the field type plus its encoding; there are additional macros for dealing with strings (GeneralString, OCTET STRING) that are encoded in the structure as two fields for pointer and length, SEQUENCE OF types encoded as pointer and (krb5_int32) length, constant integer values that get encoded but aren't represented in the structure, and a couple other oddball cases. There are variants of most of them for handling optional fields; a helper function (one per sequence type that has optional fields) is called and returns an "unsigned int" bit mask, and each field descriptor holds either a bit position to check for optional fields, or -1 for required fields. Since most of the Kerberos types have context tags on each sequence element, to optimize for this in the first cut, each field descriptor has a tag value as well, with -1 meaning no tag is to be added. (No separate macros for untagged fields currently.) In both of these cases, it probably would've been more compact to encode N+1 and use an unsigned type. That can be fixed up later if needed. So, we get, for example: /* KRB-PRIV ::= [APPLICATION 21] SEQUENCE { pvno [0] INTEGER (5), msg-type [1] INTEGER (21), -- NOTE: there is no [2] tag enc-part [3] EncryptedData -- EncKrbPrivPart } */ static const struct field_info priv_fields[] = { FIELD_INT_IMM(KVNO, 0), FIELD_INT_IMM(ASN1_KRB_PRIV, 1), FIELDOF_NORM(krb5_priv, encrypted_data, enc_part, 3), }; DEFSEQTYPE(untagged_priv, krb5_priv, priv_fields, 0); DEFAPPTAGGEDTYPE(krb5_priv, 21, untagged_priv); The use of the C type name in the FIELDOF_NORM macro has to be repeated for each field entry (except for "immediate" integer values) in the current incarnation, unfortunately, though I could redefine a macro named TYPE before each sequence description and make the macro look for that name. While these structures are hand-maintained for now, I think it's better to keep them around and obvious. The FIELDOF_NORM expansion uses the hidden typedefname created for the "encrypted_data" descriptor to type-check the "enc_part" field of "krb5_priv" and ensure that it's of type "krb5_enc_data". As the functions implementing the encoding engine pass around void pointers all the time, this is the only place to fit the type checking in. Then, to get an actual encoder function, another macro: MAKE_FULL_ENCODER(encode_krb5_priv, krb5_priv); ... which uses the implicit typedefs again to create a function that takes the desired pointer types (not void*) and generates a krb5_data holding the encoding, or an error code. The function declarations still have to be managed manually, but the goal was that the existing ones should be applicable, and aside from fixing a couple minor cases that were kind of bogus to begin with, like not using "const" consistently, or awkward, like encoding two inputs into one output. It was intended that in the cases where actual functions are needed, they are mostly very small wrapper functions. For example, any encoder function produced by MAKE_FULL_ENCODER converts the input pointer to void* and calls a common support routine with the appropriate type descriptor info; this routine allocates a temporary buffer and invokes the (recursive) encode-via-descriptor process, and copies the result into an output buffer. So functions like encode_krb5_priv will be small. The descriptor structures are kind of large at the moment, mostly because depending on the type of thing being described, we want various function or object pointers of different types and they're currently different fields; with some casting or designated union initialization, I can make them smaller. Even so, I've already got a fair size reduction (27K -> 7.5K code + 10K tables, without the PKINIT or LDAP code), though unfortunately the tables require load-time relocations now. Tom and I discussed some possible extensions to this, some of which I don't think I'm going to have time for right now, like using a script to read a file with similar data and generate C code, possibly multiple separate bits of C code for each sequence or type, which could make (for example) the type-checking more obvious in the generated code, while still optimizing it away to no run-time code. It could also get rid of the multiple uses of the same C type name while still having an input format that makes it clear what type is being used where. Having some mechanism to export and import these type descriptors, better than just exporting the type_ variables, is also very desirable. Tom and I talked about perhaps using a registration function and name strings associated with each descriptor you want to export, so for example "octetstring/krb5_data" might be a name you might attach to one, and perhaps a routine would be provided to look up a type descriptor by name, or process a table of them, for use by an external module like PKINIT or the LDAP KDB back end, both of which currently have their ASN.1 code in the main Kerberos library. Anyways, those may come later. I think I've covered the general idea, and should have code ready for review in not too long... Ken From paul.moore at centrify.com Tue Oct 21 19:25:18 2008 From: paul.moore at centrify.com (Paul Moore) Date: Tue, 21 Oct 2008 16:25:18 -0700 Subject: ASN.1 encoding in MIT Kerberos In-Reply-To: References: Message-ID: have u looked at the ber encoder in the openldap project, it is 100% separable from the ldap code base and is a joy to use it uses the printf and scanf idioms to read and write ber/der packets -----Original Message----- From: krbdev-bounces at MIT.EDU [mailto:krbdev-bounces at MIT.EDU] On Behalf Of Ken Raeburn Sent: Tuesday, October 21, 2008 4:10 PM To: krbdev at mit.edu Dev List Subject: ASN.1 encoding in MIT Kerberos Hi. I've been working a bit lately on reworking the ASN.1 encoders in the MIT Kerberos code. I'm hoping to have something ready to put into the source tree soon, probably in the next couple of weeks, so I thought I'd send out a note describing what I'm doing and see if anyone has comments. First: Yes, we know our ASN.1 encoders are ugly and hard to deal with, and in the long term, we should replace them. But using ASN.1 compilers generally involves using new data structures generated by the tools, and since many of our current data structures are exposed in our API, that means either translating at run time, including additional allocations, to convert between different representations, or banging on the generated code from the compiler (or the compiler itself) until it can work with our existing data structures. So in the *short* term, we're trying to come up with something that's both a bit more comprehensible, and a bit more structured so as to reduce the opportunities for errors in writing support for new message types. If it winds up being more compact than our current encoders, so much the better. The short-term project is what I've been working on -- a mostly table- driven encoder targeted primarily at the Kerberos protocol. It only encodes DER, doesn't have many of the primitive ASN.1 types that we don't use, is optimized for sequences where field elements are usually tagged, doesn't handle arbitrarily large tag values, etc. It's not intended to be a fully-functional general-purpose ASN.1 encoder at this stage. I'm also not tackling the decoders at this time. Doing the encoders gets us tables describing the ASN.1 and C data structures to a large degree, and perhaps this can be a starting point for future work on the decoders, but reworking the encoders is a more manageable initial step. ------ Since we don't have a unique mapping in either direction between ASN.1 types and C types, each object we describe is a combination of a C type and an ASN.1 encoding for it; krb5_data encoded as OCTET STRING is different from krb5_data encoded as GeneralString. Each of these gets a "descriptor" name associated with it when we define it. The current revision still works entirely in C code, using helper macros, but I hope they'll be at least somewhat clearer than the existing pile of macros. Two sets of macros are defined. The first set is for defining a C/ASN. 1 type descriptor. You supply a descriptor name and other parameters, such as the C type, or info on sequence fields, or a primitive encoding function. For example: DEFFNTYPE(gstring_data, krb5_data, asn1_encode_generalstring_data_at); DEFPTRTYPE(gstring_data_ptr,gstring_data); Here "gstring_data" becomes a descriptor name for a GeneralString encoded from a krb5_data structure using the indicated function, which takes as one of its arguments a pointer to the krb5_data. If your data structure includes a krb5_data that you want encoded as a GeneralString, you use "gstring_data" to describe it; if it contains a krb5_data*, you would use "gstring_data_ptr", which is defined as encoding the same thing as "gstring_data" but starting with an additional level of indirection. There are also macros for defining descriptors for SEQUENCE types, SEQUENCE OF defined as a null- terminated array of pointers to a base type, an encoding of another type with an APPLICATION tag added, etc. The various DEF*TYPE macros always define a variable type_ that encodes the information about the type -- size, how to encode it, etc. They also define typedefnames associated with the descriptor name so that, for example, when describing a structure field using a descriptor name, we can inject some compile-time code to verify that the structure field has the C type indicated by the descriptor. (Currently that works by creating a "?:" expression using pointers to the expected type and the actual field, so if there's a mismatch, you get a warning or error, but it may refer to a conditional operator you never typed in, so unfortunately it can be a little obscure.) The second set of macros defines fields of a sequence/structure. "Normal" fields are indicated by the C field name and a descriptor describing the field type plus its encoding; there are additional macros for dealing with strings (GeneralString, OCTET STRING) that are encoded in the structure as two fields for pointer and length, SEQUENCE OF types encoded as pointer and (krb5_int32) length, constant integer values that get encoded but aren't represented in the structure, and a couple other oddball cases. There are variants of most of them for handling optional fields; a helper function (one per sequence type that has optional fields) is called and returns an "unsigned int" bit mask, and each field descriptor holds either a bit position to check for optional fields, or -1 for required fields. Since most of the Kerberos types have context tags on each sequence element, to optimize for this in the first cut, each field descriptor has a tag value as well, with -1 meaning no tag is to be added. (No separate macros for untagged fields currently.) In both of these cases, it probably would've been more compact to encode N+1 and use an unsigned type. That can be fixed up later if needed. So, we get, for example: /* KRB-PRIV ::= [APPLICATION 21] SEQUENCE { pvno [0] INTEGER (5), msg-type [1] INTEGER (21), -- NOTE: there is no [2] tag enc-part [3] EncryptedData -- EncKrbPrivPart } */ static const struct field_info priv_fields[] = { FIELD_INT_IMM(KVNO, 0), FIELD_INT_IMM(ASN1_KRB_PRIV, 1), FIELDOF_NORM(krb5_priv, encrypted_data, enc_part, 3), }; DEFSEQTYPE(untagged_priv, krb5_priv, priv_fields, 0); DEFAPPTAGGEDTYPE(krb5_priv, 21, untagged_priv); The use of the C type name in the FIELDOF_NORM macro has to be repeated for each field entry (except for "immediate" integer values) in the current incarnation, unfortunately, though I could redefine a macro named TYPE before each sequence description and make the macro look for that name. While these structures are hand-maintained for now, I think it's better to keep them around and obvious. The FIELDOF_NORM expansion uses the hidden typedefname created for the "encrypted_data" descriptor to type-check the "enc_part" field of "krb5_priv" and ensure that it's of type "krb5_enc_data". As the functions implementing the encoding engine pass around void pointers all the time, this is the only place to fit the type checking in. Then, to get an actual encoder function, another macro: MAKE_FULL_ENCODER(encode_krb5_priv, krb5_priv); ... which uses the implicit typedefs again to create a function that takes the desired pointer types (not void*) and generates a krb5_data holding the encoding, or an error code. The function declarations still have to be managed manually, but the goal was that the existing ones should be applicable, and aside from fixing a couple minor cases that were kind of bogus to begin with, like not using "const" consistently, or awkward, like encoding two inputs into one output. It was intended that in the cases where actual functions are needed, they are mostly very small wrapper functions. For example, any encoder function produced by MAKE_FULL_ENCODER converts the input pointer to void* and calls a common support routine with the appropriate type descriptor info; this routine allocates a temporary buffer and invokes the (recursive) encode-via-descriptor process, and copies the result into an output buffer. So functions like encode_krb5_priv will be small. The descriptor structures are kind of large at the moment, mostly because depending on the type of thing being described, we want various function or object pointers of different types and they're currently different fields; with some casting or designated union initialization, I can make them smaller. Even so, I've already got a fair size reduction (27K -> 7.5K code + 10K tables, without the PKINIT or LDAP code), though unfortunately the tables require load-time relocations now. Tom and I discussed some possible extensions to this, some of which I don't think I'm going to have time for right now, like using a script to read a file with similar data and generate C code, possibly multiple separate bits of C code for each sequence or type, which could make (for example) the type-checking more obvious in the generated code, while still optimizing it away to no run-time code. It could also get rid of the multiple uses of the same C type name while still having an input format that makes it clear what type is being used where. Having some mechanism to export and import these type descriptors, better than just exporting the type_ variables, is also very desirable. Tom and I talked about perhaps using a registration function and name strings associated with each descriptor you want to export, so for example "octetstring/krb5_data" might be a name you might attach to one, and perhaps a routine would be provided to look up a type descriptor by name, or process a table of them, for use by an external module like PKINIT or the LDAP KDB back end, both of which currently have their ASN.1 code in the main Kerberos library. Anyways, those may come later. I think I've covered the general idea, and should have code ready for review in not too long... Ken _______________________________________________ krbdev mailing list krbdev at mit.edu https://mailman.mit.edu/mailman/listinfo/krbdev From raeburn at MIT.EDU Tue Oct 21 20:06:26 2008 From: raeburn at MIT.EDU (Ken Raeburn) Date: Tue, 21 Oct 2008 20:06:26 -0400 Subject: ASN.1 encoding in MIT Kerberos In-Reply-To: References: Message-ID: <64317D11-94DF-4CC5-B1E8-EDCC4172E8F0@MIT.EDU> On Oct 21, 2008, at 19:25, Paul Moore wrote: > have u looked at the ber encoder in the openldap project, it is 100% > separable from the ldap code base and is a joy to use > > it uses the printf and scanf idioms to read and write ber/der packets I had not looked at it; thanks for the pointer. It looks like the encoder does some extra copying when you have sequences containing sequences containing... which we do. Still, it's probably better than the backwards copying we do (twice!). The use of printf/scanf idioms are interesting, though I'm a little concerned about the lack of type checking with that style of interface. Still, unlike the other ASN.1 packages I've seen, it looks like this would be more easily adaptable to our existing data structures. We should definitely look into this one further when we have time to do real work on our ASN.1 code... Ken From ghudson at MIT.EDU Thu Oct 23 17:00:54 2008 From: ghudson at MIT.EDU (ghudson@MIT.EDU) Date: Thu, 23 Oct 2008 17:00:54 -0400 (EDT) Subject: String handling in krb5 Message-ID: <200810232100.m9NL0sRf020960@outgoing.mit.edu> Based on the excellent feedback in the previous discussion thread (http://mailman.mit.edu/pipermail/krbdev/2008-October/006975.html) and a survey of the current string handling code in krb5, we have arrived at a tentative resolution. First, we'll be recommending strdup, asprintf, and snprintf when they are applicable. I've added an SNPRINTF_OVERFLOW macro to k5-platform.h. It will be the recommended way to check for an overflow from an snprintf result. It avoids a signed/unsigned comparison and handles the case of non-conforming snprintf implementations returning -1 on overflow. Second, we'll be changing the build system to ensure that strlcpy and strlcat are available. strlcpy will be recommended for simple copies of a single string into a fixed-sized buffer, but strlcpy/strlcat will also be an option for multi-step string construction if no other options are desirable. Third, we'll be introducing a string buffer module for internal use only, which I'll call k5buf. The idea is to allow multi-step string construction within a dynamic or fixed-sized buffer, without requiring an error check at each step. Errors need only be checked when it is time to retrieve the constructed value. The 30-second API overview is: void krb5int_buf_init_fixed(struct k5buf *buf, char *data, size_t size); void krb5int_buf_init_dynamic(struct k5buf *buf); void krb5int_buf_add(struct k5buf *buf, const char *data); void krb5int_buf_add_len(struct k5buf *buf, const char *data, size_t len); void krb5int_buf_truncate(struct k5buf *buf, size_t len); char *krb5int_buf_cstr(struct k5buf *buf); /* returns NULL on error */ ssize_t krb5int_buf_len(struct k5buf *buf); /* returns -1 on error */ void krb5int_free_buf(struct k5buf *buf); /* dynamic buffers only */ If a truncation or allocation failure happens, the buffer remembers that it is in an error state and ignores subsequent modifications. The caller will detect the failure when it calls krb5int_buf_cstr(). The k5buf module will typically only be used for the most complicated cases of string construction which cannot be reduced to asprintf() or snprintf() or simpler. These cases are not terribly common; I found 20-25 of them in the code base during my survey. k5buf is not intended to become part of the krb5 API or part of the prototype of any internal function (except maybe a static helper function here or there). It's a tool, not a way of life. Here is what the coding practice section for string handling will look like: ----- Dynamically allocated buffers are preferred to fixed-sized buffers. When using dynamic buffers: * Use strdup or asprintf for simple constructions. * Use the k5buf module for complex constructions. If this is not desirable, strlcpy and strlcat are valid alternatives. When using fixed-sized buffers: * Use strlcpy for simple copies. * Use snprintf for simple compound constructions. Avoid using precision or field width specifiers in snprintf format strings. * To check for truncation when using snprintf, use the following approach: result = snprintf(buffer, sizeof(buffer), "format string", ...); if (SNPRINTF_OVERFLOW(result, sizeof(buffer)) handle_overflow_error; The SNPRINTF_OVERFLOW macro is defined in k5-platform.h. * Use the k5buf module for complex constructions. If this is not desirable, strlcpy and strlcat are valid alternatives. From Nicolas.Williams at sun.com Thu Oct 23 17:37:25 2008 From: Nicolas.Williams at sun.com (Nicolas Williams) Date: Thu, 23 Oct 2008 16:37:25 -0500 Subject: String handling in krb5 In-Reply-To: <200810232100.m9NL0sRf020960@outgoing.mit.edu> References: <200810232100.m9NL0sRf020960@outgoing.mit.edu> Message-ID: <20081023213724.GY21103@Sun.COM> I'd add: don't use field width specifiers for %s. From tlyu at MIT.EDU Thu Oct 23 17:53:36 2008 From: tlyu at MIT.EDU (Tom Yu) Date: Thu, 23 Oct 2008 17:53:36 -0400 Subject: String handling in krb5 In-Reply-To: <20081023213724.GY21103@Sun.COM> (Nicolas Williams's message of "Thu, 23 Oct 2008 16:37:25 -0500") References: <200810232100.m9NL0sRf020960@outgoing.mit.edu> <20081023213724.GY21103@Sun.COM> Message-ID: Nicolas Williams writes: > I'd add: don't use field width specifiers for %s. Unfortunately, we often need to use the "%.*s" construct to deal with unterminated strings such as may appear from GSS-API. We could add an additional interface to handle these.