﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>IT博客-毒菇求Buy-文章分类-HTTP</title><link>http://www.cnitblog.com/alsan/category/127.html</link><description>Not now, when?</description><language>zh-cn</language><lastBuildDate>Sat, 01 Oct 2011 16:20:59 GMT</lastBuildDate><pubDate>Sat, 01 Oct 2011 16:20:59 GMT</pubDate><ttl>60</ttl><item><title>Javascript Programming Conventions</title><link>http://www.cnitblog.com/alsan/articles/8069.html</link><dc:creator>毒菇求Buy</dc:creator><author>毒菇求Buy</author><pubDate>Sat, 25 Mar 2006 01:14:00 GMT</pubDate><guid>http://www.cnitblog.com/alsan/articles/8069.html</guid><wfw:comment>http://www.cnitblog.com/alsan/comments/8069.html</wfw:comment><comments>http://www.cnitblog.com/alsan/articles/8069.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/alsan/comments/commentRss/8069.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/alsan/services/trackbacks/8069.html</trackback:ping><description><![CDATA[
		<p style="FONT-SIZE: 12px; FONT-FAMILY: Verdana">This document follows the basic outline of the Java Programming Conventions Guide, a copy of which may be found at <a href="http://geosoft.no/javastyle.html">http://geosoft.no/javastyle.html</a></p>
		<div style="FONT-SIZE: 16px; COLOR: #800000; FONT-FAMILY: Verdana">Conventions</div>
		<p style="FONT-SIZE: 12px; FONT-FAMILY: Verdana">Any violation to this guide is allowed if it enhances readability.</p>
		<p style="FONT-SIZE: 12px; FONT-FAMILY: Verdana">Guidelines in this document are informed by discussions carried out among the Dojo core developers. The most weight has been given to considerations that impact external developer interaction with Dojo code and APIs. Rules such as whitespace placement are of a much lower order importance fo Dojo developers, but should be followed in the main in order to improve developer coordination.</p>
		<div style="FONT-SIZE: 16px; COLOR: #800000; FONT-FAMILY: Verdana">Quick Reference</div>
		<p style="FONT-SIZE: 12px; FONT-FAMILY: Verdana">Table of core API naming constructs:</p>
		<table style="FONT-SIZE: 12px; FONT-FAMILY: Verdana" border="1">
				<tbody>
						<tr>
								<th>Construct</th>
								<th>Convention</th>
								<th>Comment</th>
						</tr>
						<tr>
								<td>package</td>
								<td>lower</td>
								<td>never multiple words</td>
						</tr>
						<tr>
								<td>class</td>
								<td>UpperLower</td>
								<td> </td>
						</tr>
						<tr>
								<td>public method</td>
								<td>lowerUpper</td>
								<td>whether class or instance method. lower_case() is acceptable only if the particular function is mimicing another API.</td>
						</tr>
						<tr>
								<td>public var</td>
								<td>lowerUpper</td>
								<td> </td>
						</tr>
						<tr>
								<td>constant</td>
								<td>UpperLower or UPPER_LOWER</td>
								<td> </td>
						</tr>
				</tbody>
		</table>
		<p style="FONT-SIZE: 12px; FONT-FAMILY: Verdana">Table of constructs that are not visible in the API, and therefore are optional and carry less weight of enforcement.</p>
		<table style="FONT-SIZE: 12px; FONT-FAMILY: Verdana" border="1">
				<tbody>
						<tr>
								<th>Construct</th>
								<th>Convention</th>
								<th>Comment</th>
						</tr>
						<tr>
								<td>private method</td>
								<td>_lowerUpper</td>
								<td> </td>
						</tr>
						<tr>
								<td>private var</td>
								<td>_lowerUpper</td>
								<td> </td>
						</tr>
						<tr>
								<td>method args</td>
								<td>_lowerUpper, lowerUpper</td>
								<td> </td>
						</tr>
						<tr>
								<td>local vars</td>
								<td>_lowerUpper, lowerUpper</td>
								<td> </td>
						</tr>
				</tbody>
		</table>
		<div style="FONT-SIZE: 16px; COLOR: #800000; FONT-FAMILY: Verdana">Naming Conventions</div>
		<ol style="FONT-SIZE: 12px; FONT-FAMILY: Verdana">
				<li>Names representing packages SHOULD be in all lower case.</li>
				<li>Names representing types (classes) MUST be nouns and written in UpperLower case: <pre style="FONT-SIZE: 12px; COLOR: black; FONT-FAMILY: Courier New , Courier, Monospace; BACKGROUND-COLOR: #ffffff">Account, EventHandler
	</pre></li>
				<li>Constants SHOULD be placed within a single object created as a holder for constants, emulating an Enum; the enum SHOULD be named appropriately, and members SHOULD be named using either UpperLower or UPPER_LOWER case: <pre style="FONT-SIZE: 12px; COLOR: black; FONT-FAMILY: Courier New , Courier, Monospace; BACKGROUND-COLOR: #ffffff">var NodeTypes = {
	Element: 1,
	DOCUMENT: 2
}
	</pre></li>
				<li>Abbreviations and acronyms SHOULD NOT be uppercase when used as a name: <pre style="FONT-SIZE: 12px; COLOR: black; FONT-FAMILY: Courier New , Courier, Monospace; BACKGROUND-COLOR: #ffffff">getInnerHtml(), getXml(), XmlDocument
	</pre></li>
				<li>Names representing methods SHOULD be verbs or verb phrases: <pre style="FONT-SIZE: 12px; COLOR: black; FONT-FAMILY: Courier New , Courier, Monospace; BACKGROUND-COLOR: #ffffff">obj.getSomeValue();
	</pre></li>
				<li>Public class variables MUST be written using upperLower case.</li>
				<li>Private class variables MAY be written using _upperLower (with preceding underscore): <pre style="FONT-SIZE: 12px; COLOR: black; FONT-FAMILY: Courier New , Courier, Monospace; BACKGROUND-COLOR: #ffffff">var MyClass = function() {
	var _buffer;
	this.doSomething = function() {
	};
}
	</pre></li>
				<li>Variables that are intended to be private, but cannot be based on the semantics of Javascript, SHOULD prepended with a "_" (underscore) char: <pre style="FONT-SIZE: 12px; COLOR: black; FONT-FAMILY: Courier New , Courier, Monospace; BACKGROUND-COLOR: #ffffff">this._somePrivateVariable = statement;
	</pre>NB Note that the above variable also follows the convention for a private variable. </li>
				<li>Generic variables SHOULD have the same name as their type: <pre style="FONT-SIZE: 12px; COLOR: black; FONT-FAMILY: Courier New , Courier, Monospace; BACKGROUND-COLOR: #ffffff">setTopic(topic);	// where topic isTypeOf Topic
	</pre></li>
				<li>All names SHOULD be written in English.</li>
				<li>Variables with a large scope SHOULD have globally unambiguious names, ambiguity MAY be distinguished by package membership. Variables with small or private scope MAY be more terse still.</li>
				<li>The name of the return object is implicit, and SHOULD be avoided in a method name: <pre style="FONT-SIZE: 12px; COLOR: black; FONT-FAMILY: Courier New , Courier, Monospace; BACKGROUND-COLOR: #ffffff">getHandler();	// NOT getEventHandler();
	</pre></li>
				<li>Public names SHOULD be as clear as necessary and SHOULD avoid unclear shortenings and contractions: <pre style="FONT-SIZE: 12px; COLOR: black; FONT-FAMILY: Courier New , Courier, Monospace; BACKGROUND-COLOR: #ffffff">MouseEventHandler	// NOT MseEvtHdlr.
	</pre>Note that, again, any context that can be determined by package membership SHOULD be used when determing if a variable name is clear. For example, a class that represents a mouse event handler: <pre style="FONT-SIZE: 12px; COLOR: black; FONT-FAMILY: Courier New , Courier, Monospace; BACKGROUND-COLOR: #ffffff">myobj.events.mouse.Handler	// NOT myobj.events.mouse.MouseEventHandler
	</pre></li>
				<li>Classes/constructors MAY be named basedon their inheritance pattern, with the base class to the right of the name: <pre style="FONT-SIZE: 12px; COLOR: black; FONT-FAMILY: Courier New , Courier, Monospace; BACKGROUND-COLOR: #ffffff">EventHandler
UIEventHandler
MouseEventHandler
	</pre>NB The base class CAN be dropped from a name if it is obviously implicit in the name: <pre style="FONT-SIZE: 12px; COLOR: black; FONT-FAMILY: Courier New , Courier, Monospace; BACKGROUND-COLOR: #ffffff">MouseEventHandler	// as opposed to MouseUIEventHandler
	</pre></li>
		</ol>
		<div style="FONT-SIZE: 16px; COLOR: #800000; FONT-FAMILY: Verdana">Specific Naming conventions</div>
		<ol style="FONT-SIZE: 12px; FONT-FAMILY: Verdana">
				<li>Ther terms get/set SHOULD NOT used where a field is accessed, unless the variable being accessed is lexically private.</li>
				<li>"is" prefix SHOULD be used for boolean variables and methods.<br />NB, Alternatives include "has", "can" and "should". </li>
				<li>The term "compute" CAN be used in methods where something is computed.</li>
				<li>The term "find" CAN be used in methods where something is looked up.</li>
				<li>Ther terms "initialize" or "init" CAN be used where an object or a concept is established.</li>
				<li>UI Control variables SHOULD be suffixed by the control type, ie: leftComboBox, topScrollPane.</li>
				<li>Plural form MUST be used to name collections.</li>
				<li>"num" prefix or "count" postfix SHOULD be used for variables representing a number of objects.</li>
				<li>Iterator variables SHOULD be called "i", "j", "k", etc.</li>
				<li>Compliment names MUST be used for compliment entities. ie: get/set, add/remove, create/destroy, start/stop, insert/delete, begin/end, etc.</li>
				<li>Abbreviations in names SHOULD be avoided.</li>
				<li>Negated boolean variable names MUST be avoided: <pre style="FONT-SIZE: 12px; COLOR: black; FONT-FAMILY: Courier New , Courier, Monospace; BACKGROUND-COLOR: #ffffff">isNotError	// are UNACCEPTABLE
	</pre></li>
				<li>Exception classes SHOULD be suffixed with "Exception" or "Error"...FIXME (trt) not sure about this?</li>
				<li>Methods returning an object MAY be named after what they return, and methods returning void after what they do.</li>
		</ol>
		<div style="FONT-SIZE: 16px; COLOR: #800000; FONT-FAMILY: Verdana">Files</div>
		<ol style="FONT-SIZE: 12px; FONT-FAMILY: Verdana">
				<li>Class or object-per-file guidelines are not yet determined.</li>
				<li>Tabs (set to 4 spaces) SHOULD be used for indentation.</li>
				<li>If your editor supports "file tags", please append the appropriate tag at the end of the file enable others to effortlessly obey the correct indentation guidelines for that file <pre style="FONT-SIZE: 12px; COLOR: black; FONT-FAMILY: Courier New , Courier, Monospace; BACKGROUND-COLOR: #ffffff">// vim:ts=4:note:tw=0:
	</pre></li>
				<li>The incompletenes of split line MUST be made obvious: <pre style="FONT-SIZE: 12px; COLOR: black; FONT-FAMILY: Courier New , Courier, Monospace; BACKGROUND-COLOR: #ffffff">var someExpression = Expression1
	+ Expression2
	+ Expression3;
	
var o = someObject.get (
		Expression1,
		Expression2,
		Expression3
	);
	</pre>Note the indentation for expression continuation is indented relative to the variable name, while indentation for parameters is relative to the method being called.<br /><br />Note also the position of the parenthesis in the method call; positioning SHOULD be similar to the use of block notation. </li>
		</ol>
		<div style="FONT-SIZE: 16px; COLOR: #800000; FONT-FAMILY: Verdana">Variables</div>
		<ol style="FONT-SIZE: 12px; FONT-FAMILY: Verdana">
				<li>Variables SHOULD be initialized where they are declared and they SHOULD be declared in the smallest scope possible. A null initialization is acceptable.</li>
				<li>Variables MUST never have a dual meaning.</li>
				<li>Related variables of the same type CAN be declared in a common statement; unrelated variables SHOULD NOT be declared in the same statement.</li>
				<li>Variables SHOULD be kept alive for a short a time as possible.</li>
				<li>Loops/iterative declarations 
<ol><li>Only loop control statements MUST be included in the "for()" construction.</li><li>Loop variables SHOULD be initialized immediately before the loop; loop variables in a "for" statement MAY be initialized in the "for" loop construction.</li><li>The use of "do...while" loops are acceptable (unlike in java)</li><li>The use of "break" and "continue" is not discouraged (unlike in Java)</li></ol></li>
				<li>Conditionals 
<ol><li>Complex conditional expressions SHOULD be avoided; use temporary boolean variables instead.</li><li>The nominal case SHOULD be put in the "if" part and the exception in the "else" part of an "if" statement.</li><li>Executable statements in conditionals MUST be avoided.</li></ol></li>
				<li>Miscellaneous 
<ol><li>The use of magic numbers in the code SHOULD be avoided; they SHOULD be declared using named "constants" instead.</li><li>Floating point constants SHOULD ALWAYS be written with decimal point ant at least one decimal.</li><li>Floating point constants SHOULD ALWAYS be written with a digit before the decimal point.</li></ol></li>
		</ol>
		<div style="FONT-SIZE: 16px; COLOR: #800000; FONT-FAMILY: Verdana">Layout</div>
		<ol style="FONT-SIZE: 12px; FONT-FAMILY: Verdana">
				<li>Block statements 
<ol><li>Block layout SHOULD BE as illustrated below: <pre style="FONT-SIZE: 12px; COLOR: black; FONT-FAMILY: Courier New , Courier, Monospace; BACKGROUND-COLOR: #ffffff">while(!isDone) {
	doSomething();
	isDone = moreToDo();
}
				</pre></li><li>If statements SHOULD have the following form: <pre style="FONT-SIZE: 12px; COLOR: black; FONT-FAMILY: Courier New , Courier, Monospace; BACKGROUND-COLOR: #ffffff">if(someCondition) {
	statements;
} else if(someOtherCondition) {
	statements;
} else {
	statements;
}
				</pre></li><li>for statements SHOULD be have the following form: <pre style="FONT-SIZE: 12px; COLOR: black; FONT-FAMILY: Courier New , Courier, Monospace; BACKGROUND-COLOR: #ffffff">for(initialization; condition; update) {
	statements;
}
				</pre></li><li>while statement SHOULD follow the form in example VI.A.1</li><li>a do...while statement SHOULD have the following form: <pre style="FONT-SIZE: 12px; COLOR: black; FONT-FAMILY: Courier New , Courier, Monospace; BACKGROUND-COLOR: #ffffff">do {
	statements;
} while(condition);
				</pre></li><li>a switch statement SHOULD have the following form: <pre style="FONT-SIZE: 12px; COLOR: black; FONT-FAMILY: Courier New , Courier, Monospace; BACKGROUND-COLOR: #ffffff">switch(condition) {
	case ABC:
		statements;
		// fall through
	case DEF:
		statements;
		break;
	default:
		statements;
		break;
}
				</pre></li><li>a try...catch...finally statement SHOULD have the following form: <pre style="FONT-SIZE: 12px; COLOR: black; FONT-FAMILY: Courier New , Courier, Monospace; BACKGROUND-COLOR: #ffffff">try {
	statements;
} catch(ex) {
	statements;
} finally {
	statements;
}
				</pre></li><li>single statement if-else, while or for MUST NOT be written without brackets, but CAN be written on the same line: <pre style="FONT-SIZE: 12px; COLOR: black; FONT-FAMILY: Courier New , Courier, Monospace; BACKGROUND-COLOR: #ffffff">if(condition) {statement;}
while(condition) {statement;}
for(initialization; condition; update) {statement;}
				</pre></li></ol></li>
				<li>Whitespace 
<ol><li>Conventional operatiors MAY be surrounded by a space (including ternary operatiors).</li><li>Reserved words SHOULD be followed by a space.</li><li>Commas SHOULD be followed by a space.</li><li>Colons MAY be surrounded by a space.</li><li>Semi-colons in for statements SHOULD be followed by a space.</li><li>Semi-colons SHOULD NOT be spreceded by a space.</li><li>Functions/method calls SHOULD NOT be followed by a space. ie:<br />doSomething(someParameter); // NOT doSomething(someParameter) </li><li>Logical units within a block SHOULD be seperated by one blank line.</li><li>Statements MAY be aligned wherever this enhances readability.</li></ol></li>
				<li>Comments 
<ol><li>Tricky code SHOULD not be commented, but rewritten.</li><li>All comments SHOULD be written in English.</li><li>Comments SHOULD be indented relative to their position in the code, preceding or to the right of the code in question.</li><li>The declaration of collection variables SHOULD be followed by a comment stating the common type of the elements in the collection.</li><li>Comments SHOULD be included to explain BLOCKS of code, to explain the point of the following block.</li><li>Comments SHOULD NOT be included for every single line of code.</li></ol></li>
		</ol>
<img src ="http://www.cnitblog.com/alsan/aggbug/8069.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/alsan/" target="_blank">毒菇求Buy</a> 2006-03-25 09:14 <a href="http://www.cnitblog.com/alsan/articles/8069.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>NTLM Authentication Scheme for HTTP</title><link>http://www.cnitblog.com/alsan/articles/361.html</link><dc:creator>毒菇求Buy</dc:creator><author>毒菇求Buy</author><pubDate>Sun, 12 Jun 2005 07:53:00 GMT</pubDate><guid>http://www.cnitblog.com/alsan/articles/361.html</guid><wfw:comment>http://www.cnitblog.com/alsan/comments/361.html</wfw:comment><comments>http://www.cnitblog.com/alsan/articles/361.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cnitblog.com/alsan/comments/commentRss/361.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/alsan/services/trackbacks/361.html</trackback:ping><description><![CDATA[<FONT style="FONT-SIZE: 12px; FONT-FAMILY: Verdana">
<H3>Introduction</H3>
<P>This is an attempt at documenting the undocumented NTLM authentication scheme used by M$'s browsers, proxies, and servers (MSIE &amp; IIS); this scheme is also sometimes referred to as the NT challenge/response (NTCR) scheme. Most of the info here is derived from three sources (see also the References section at the end of this document): Paul Ashton's work on the NTLM security holes, the encryption documentation from Samba, and network snooping. Since most of this info is reverse-engineered it is bound to contain errors; however, at least one client and one server have been implemented according to this data and work successfully in conjunction with M$'s browser, proxies and servers.<BR><BR>Note that this scheme is not as secure as Digest and some other schemes; it is slightly better than the Basic authentication scheme, however.<BR><BR>Also note that this scheme is not an http authentication scheme - it's a connection authentication scheme which happens to (mis-)use http status codes and headers (and even those incorrectly).<BR><BR></P>
<H3>HTTP Handshake</H3>
<P>When a client needs to authenticate itself to a proxy or server using the NTLM scheme then the following 4-way handshake takes place (only parts of the request and status line and the relevant handers are shown here; "C" is the client, "S" is the server):<BR></P>
<DIV style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 4px; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid">
<TABLE style="FONT-SIZE: 10px">
<TBODY>
<TR>
<TD>1:</TD>
<TD>C</TD>
<TD>-&gt;</TD>
<TD>S</TD>
<TD>&nbsp;&nbsp;</TD>
<TD><STRONG>GET...</STRONG></TD></TR>
<TR>
<TD>2:</TD>
<TD>C</TD>
<TD>&lt;-</TD>
<TD>S</TD>
<TD>&nbsp;&nbsp;</TD>
<TD><STRONG>401 Unauthorized</STRONG></TD></TR>
<TR>
<TD colSpan=5>&nbsp;</TD>
<TD><STRONG>WWW-Authenticate: NTLM</STRONG></TD></TR>
<TR>
<TD>3:</TD>
<TD>C</TD>
<TD>-&gt;</TD>
<TD>S</TD>
<TD>&nbsp;&nbsp;</TD>
<TD><STRONG>GET...</STRONG></TD></TR>
<TR>
<TD colSpan=5>&nbsp;</TD>
<TD><STRONG>Authorization: NTLM &lt;base64-encoded type-1-message&gt;</STRONG></TD></TR>
<TR>
<TD>4:</TD>
<TD>C</TD>
<TD>&lt;-</TD>
<TD>S</TD>
<TD>&nbsp;&nbsp;</TD>
<TD><STRONG>401 Unauthorized</STRONG></TD></TR>
<TR>
<TD colSpan=5>&nbsp;</TD>
<TD><STRONG>WWW-Authenticate: NTLM &lt;base64-encoded type-2-message&gt;</STRONG></TD></TR>
<TR>
<TD>5:</TD>
<TD>C</TD>
<TD>-&gt;</TD>
<TD>S</TD>
<TD>&nbsp;&nbsp;</TD>
<TD><STRONG>GET...</STRONG></TD></TR>
<TR>
<TD colSpan=5>&nbsp;</TD>
<TD><STRONG>Authorization: NTLM &lt;base64-encoded type-3-message&gt;</STRONG></TD></TR>
<TR>
<TD>6:</TD>
<TD>C</TD>
<TD>&lt;-</TD>
<TD>S</TD>
<TD>&nbsp;&nbsp;</TD>
<TD><STRONG>200 Ok</STRONG></TD></TR></TBODY></TABLE></DIV>
<H3>Messages</H3>
<P>The three messages sent in the handshake are binary structures. Each one is described below as a pseudo-C struct and in a memory layout diagram. <SPAN style="FONT-STYLE: italic">byte</SPAN> is an 8-bit field; All fields are unsigned. Numbers are stored in little-endian order. Struct fields named <SPAN style="FONT-STYLE: italic">zero</SPAN> contain all zeros. An array length of "*" indicates a variable length field. Hexadecimal numbers and quoted characters in the comments of the struct indicate fixed values for the given field.<BR><BR>The field <SPAN style="FONT-STYLE: italic">flags</SPAN> is presumed to contain flags, but their significance is unknown; the values given are just those found in the packet traces.</P>
<H4>Type-1 Message</H4>
<DIV style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 4px; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid">
<P>This message contains the host name and the NT domain name of the client.</P><PRE style="FONT-SIZE: 10px; FONT-FAMILY: Verdana">struct {
	byte	protocol[8];	// 'N', 'T', 'L', 'M', 'S', 'S', 'P', '\0'
	byte	type;		// 0x01
	byte	zero[3];
	short	flags;		// 0xb203
	byte	zero[2];
	
	short	dom_len;		// domain string length
	short	dom_len;		// domain string length
	short	dom_off;		// domain string offset
	
	short	host_len;		// host string length
	short	host_len;		// host string length
	short	host_off;		// host string offset (always 0x20)
	byte	zero[2];
	
	byte	host[*];		// host string (ASCII)
	byte	dom[*];		// domain string (ASCII)
} type-1-message;
</PRE></DIV><BR><BR>
<TABLE style="FONT-SIZE: 10px" align=center border=1>
<TBODY>
<TR align=middle>
<TH>&nbsp;</TH>
<TH>0</TH>
<TH>1</TH>
<TH>2</TH>
<TH>3</TH></TR>
<TR align=middle>
<TH>0</TH>
<TD>'N'</TD>
<TD>'T'</TD>
<TD>'L'</TD>
<TD>'M'</TD></TR>
<TR align=middle>
<TH>4</TH>
<TD>'S'</TD>
<TD>'S'</TD>
<TD>'P'</TD>
<TD>0</TD></TR>
<TR align=middle>
<TH>8</TH>
<TD>1</TD>
<TD>0</TD>
<TD>0</TD>
<TD>0</TD></TR>
<TR align=middle>
<TH>12</TH>
<TD>0x03</TD>
<TD>0xb2</TD>
<TD>0</TD>
<TD>0</TD></TR>
<TR align=middle>
<TH>16</TH>
<TD colSpan=2>domain length</TD>
<TD colSpan=2>domain length</TD></TR>
<TR align=middle>
<TH>20</TH>
<TD colSpan=2>domain offset</TD>
<TD>0</TD>
<TD>0</TD></TR>
<TR align=middle>
<TH>24</TH>
<TD colSpan=2>host length</TD>
<TD colSpan=2>host length</TD></TR>
<TR align=middle>
<TH>28</TH>
<TD colSpan=2>host offset</TD>
<TD>0</TD>
<TD>0</TD></TR>
<TR align=middle>
<TH>32</TH>
<TD colSpan=4>host string<BR>domain string</TD></TR></TBODY></TABLE><BR><BR>
<P>The host and domain strings are ASCII (or possibly ISO-8859-1), are uppercased, and are not nul-terminated. The host name is only the host name, not the FQDN (e.g. just "GOOFY", not "GOOFY.DISNEY.COM"). The offsets refer to the offset of the specific field within the message, and the lengths are the length of specified field. For example, in the above message host_off = 32 and dom_off = host_off + host_len. Note that the lengths are included twice (for some unfathomable reason).</P>
<H4>Type-2 Message</H4>
<DIV style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 4px; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid">
<P>This message contains the server's NTLM challenge.</P><PRE style="FONT-SIZE: 10px; FONT-FAMILY: Verdana">struct {
	byte	protocol[8];	// 'N', 'T', 'L', 'M', 'S', 'S', 'P', '\0'
	byte	type;		// 0x02
	byte	zero[7];
	short	msg_len;		// 0x28
	byte	zero[2];
	short	flags;		// 0x8201
	byte	zero[2];
	
	byte	nonce[8];		// nonce
	byte	zero[8];
} type-2-message;
</PRE></DIV><BR><BR>
<TABLE style="FONT-SIZE: 10px" align=center border=1>
<TBODY>
<TR align=middle>
<TH>&nbsp;</TH>
<TH>0</TH>
<TH>1</TH>
<TH>2</TH>
<TH>3</TH></TR>
<TR align=middle>
<TH>0</TH>
<TD>'N'</TD>
<TD>'T'</TD>
<TD>'L'</TD>
<TD>'M'</TD></TR>
<TR align=middle>
<TH>4</TH>
<TD>'S'</TD>
<TD>'S'</TD>
<TD>'P'</TD>
<TD>0</TD></TR>
<TR align=middle>
<TH>8</TH>
<TD>2</TD>
<TD>0</TD>
<TD>0</TD>
<TD>0</TD></TR>
<TR align=middle>
<TH>12</TH>
<TD>0</TD>
<TD>0</TD>
<TD>0</TD>
<TD>0</TD></TR>
<TR align=middle>
<TH>16</TH>
<TD colSpan=2>message len</TD>
<TD>0</TD>
<TD>0</TD></TR>
<TR align=middle>
<TH>20</TH>
<TD>0x01</TD>
<TD>0x82</TD>
<TD>0</TD>
<TD>0</TD></TR>
<TR align=middle>
<TH>24</TH>
<TD colSpan=4 rowSpan=2>server nonce</TD></TR>
<TR align=middle>
<TH>28</TH></TR>
<TR align=middle>
<TH>32</TH>
<TD>0</TD>
<TD>0</TD>
<TD>0</TD>
<TD>0</TD></TR>
<TR align=middle>
<TH>36</TH>
<TD>0</TD>
<TD>0</TD>
<TD>0</TD>
<TD>0</TD></TR></TBODY></TABLE><BR><BR>
<P>The nonce is used by the client to create the LanManager and NT responses (see <A href="#hashes">Password Hashes</A>). It is an array of 8 arbitrary bytes. The message length field contains the length of the complete message, which in this case is always 40.</P>
<H4>Type-3 Message</H4>
<DIV style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 4px; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid">
<P>This message contains the username, host name, NT domain name, and the two "responses".</P><PRE style="FONT-SIZE: 10px; FONT-FAMILY: Verdana">struct {
	byte	protocol[8];	// 'N', 'T', 'L', 'M', 'S', 'S', 'P', '\0'
	byte	type;		// 0x03
	byte	zero[3];
	
	short	lm_resp_len;	// LanManager response length (always 0x18)
	short	lm_resp_len;	// LanManager response length (always 0x18)
	short	lm_resp_off;	// LanManager response offset
	byte	zero[2];
	
	short	nt_resp_len;	// NT response length (always 0x18)
	short	nt_resp_len;	// NT response length (always 0x18)
	short	nt_resp_off;	// NT response offset
	byte	zero[2];
	
	short	dom_len;		// domain string length
	short	dom_len;		// domain string length
	short	dom_off;		// domain string offset (always 0x40)
	byte	zero[2];
	
	short	user_len;		// username string length
	short	user_len;		// username string length
	short	user_off;		// username string offset
	byte	zero[2];
	
	short	host_len;		// host string length
	short	host_len;		// host string length
	short	hsot_off;		// host string offset
	byte	zero[6];
	
	short	msg_len;		// message length
	byte	zero[2];
	
	byte	dom[*];		// domain string (unicode UTF-16LE)
	byte	user[*]		// username string (unicode UTF-16LE)
	byte	host[*];		// host string (unicode UTF-16LE)
	byte	lm_resp[*];	// LanManager response
	byte	nt_resp[*];	// NT response
} type-3-message;
</PRE></DIV><BR><BR>
<TABLE style="FONT-SIZE: 10px" align=center border=1>
<TBODY>
<TR align=middle>
<TH>&nbsp;</TH>
<TH>0</TH>
<TH>1</TH>
<TH>2</TH>
<TH>3</TH></TR>
<TR align=middle>
<TH>0</TH>
<TD>'N'</TD>
<TD>'T'</TD>
<TD>'L'</TD>
<TD>'M'</TD></TR>
<TR align=middle>
<TH>4</TH>
<TD>'S'</TD>
<TD>'S'</TD>
<TD>'P'</TD>
<TD>0</TD></TR>
<TR align=middle>
<TH>8</TH>
<TD>3</TD>
<TD>0</TD>
<TD>0</TD>
<TD>0</TD></TR>
<TR align=middle>
<TH>12</TH>
<TD colSpan=2>LM-Resp len</TD>
<TD colSpan=2>LM-Resp len</TD></TR>
<TR align=middle>
<TH>16</TH>
<TD colSpan=2>LM-Resp off</TD>
<TD>0</TD>
<TD>0</TD></TR>
<TR align=middle>
<TH>20</TH>
<TD colSpan=2>NT-Resp len</TD>
<TD colSpan=2>NT-Resp len</TD></TR>
<TR align=middle>
<TH>24</TH>
<TD colSpan=2>NT-Resp off</TD>
<TD>0</TD>
<TD>0</TD></TR>
<TR align=middle>
<TH>28</TH>
<TD colSpan=2>domain len</TD>
<TD colSpan=2>domain len</TD></TR>
<TR align=middle>
<TH>32</TH>
<TD colSpan=2>domain off</TD>
<TD>0</TD>
<TD>0</TD></TR>
<TR align=middle>
<TH>36</TH>
<TD colSpan=2>username len</TD>
<TD colSpan=2>username len</TD></TR>
<TR align=middle>
<TH>40</TH>
<TD colSpan=2>username off</TD>
<TD>0</TD>
<TD>0</TD></TR>
<TR align=middle>
<TH>44</TH>
<TD colSpan=2>host len</TD>
<TD colSpan=2>host len</TD></TR>
<TR align=middle>
<TH>48</TH>
<TD colSpan=2>host off</TD>
<TD>0</TD>
<TD>0</TD></TR>
<TR align=middle>
<TH>52</TH>
<TD>0</TD>
<TD>0</TD>
<TD>0</TD>
<TD>0</TD></TR>
<TR align=middle>
<TH>56</TH>
<TD colSpan=2>message len</TD>
<TD>0</TD>
<TD>0</TD></TR>
<TR align=middle>
<TH>60</TH>
<TD>0x01</TD>
<TD>0x82</TD>
<TD>0</TD>
<TD>0</TD></TR>
<TR align=middle>
<TH>64</TH>
<TD colSpan=4>domain string<BR>user string<BR>host string<BR>LanManager-response<BR>NT-response</TD></TR></TBODY></TABLE><BR><BR>
<P>The host, domain, and username strings are in Unicode (UTF-16, little-endian) and are not nul-terminated; the host and domain names are in upper case. The lengths of the response strings are 24.</P>
<H3>Password Hashes</H3>
<P>To calculate the two response strings two password hashes are used: the LanManager password hash and the NT password hash. These are described in detail at the beginning of the Samba <A href="htttp://de.samba.org/samba/ftp/docs/htmldocs/ENCRYPTION.html">ENCRYPTION.html</A> document. However, a few things are not clear (such as what the magic constant for the LanManager hash is), so here is some almost-C code which claculates the two responses. Inputs are <SPAN style="FONT-STYLE: italic">passw</SPAN> and <SPAN style="FONT-STYLE: italic">nonce</SPAN>, the results are in <SPAN style="FONT-STYLE: italic">lm_resp</SPAN> and <SPAN style="FONT-STYLE: italic">nt_resp</SPAN>.</P>
<DIV style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 4px; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid"><PRE style="FONT-SIZE: 10px; FONT-FAMILY: Verdana">// setup LanManager password
char lm_pw[14];
int len = strlen(passwd);

if(14 &lt; len) {
	len = 14;
}

for(idx = 0; idx &lt; len; idx++) {
	lm_pw[idx] = toupper(passwd[idx];
}

for(; idx &lt; 14; idx++) {
	lm_pw[idx] = 0;
}

// create LanManager hashed password
unsigned char magic[] = {0x4B, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25};
unsigned char lm_hpw[21];
des_key_schedule ks;

setup_des_key(lm_pw, ks);
des_ecb_encrypt(magic, lm_hw, ks);

setup_des_key(lm_pw + 7, ks);
des_ecb_encrypt(magic, lm_hpw + 8, ks);

memset(lm_hpw + 16, 0, 5);

// create NT hashed password
int len = strlen(passw);
char nt_pw[2 * len];

for(idx=0; idx &lt; len; idx++) {
	nt_pw[2 * idx] = passw[idx];
	nt_pw[2 * idx + 1] = 0;
}

unsigned char nt_hpw[21];
MD4_CTX context;
MD4Init(&amp;context);
MD4Update(&amp;context, nt_pw, 2 * len);
ND4Final(nt_hpw, &amp;context);

memset(nt_hpw + 16, 0, 5);

// create responses
unsinged lm_resp[24], nt_resp[24];
calc_resp(lm_hpw, nonce, lm_resp);
calc_resp(nt_hpw, nonce, nt_resp);

Helpers:
// takes a 21 byte array and treats it as 3 56-bit DES keys. The 8 byte plaintext is encrypted 
// with each key and the resulting 24 bytes are stored in the results array.
void calc_resp(unsigned char* keys, unsigned char* plaintext, unsigned char* results) {
	des_key_schedule ks;
	
	setup_des_key(keys, ks);
	des_ecb_encrypt((des_cblock*)plaintext, (des_cblock*)results, ks, DES_ENCRYPT);
	
	setup_des_key(keys + 7, ks);
	des_ecb_encrypt((des_cblock*)plaintext, (des_cblock*)(results + 8), ks, DES_ENCRYPT);
	
	setup_des_key(keys + 14, ks);
	des_ecb_encrypt((des_cblock*)plaintext, (des_cblock*)(results + 16), ks, DES_ENCRYPT);
}

// turns a 56 bit key into the 64 bit, odd parity key and sets the key.
// The key schedule ks is also set.
void setup_des_key(unsigned char key_56[], des_key_schedule ks) {
	des_cblock key;
	
	key[0] = key_56[0];
	key[1] = ((key_56[0] &lt;&lt; 7) &amp; 0xff) | (key _56[1] &gt;&gt; 1);
	key[2] = ((key_56[1] &lt;&lt; 6) &amp; 0xff) | (key _56[2] &gt;&gt; 2);
	key[3] = ((key_56[2] &lt;&lt; 5) &amp; 0xff) | (key _56[3] &gt;&gt; 3);
	key[1] = ((key_56[3] &lt;&lt; 4) &amp; 0xff) | (key _56[4] &gt;&gt; 4);
	key[1] = ((key_56[4] &lt;&lt; 3) &amp; 0xff) | (key _56[5] &gt;&gt; 5);
	key[1] = ((key_56[5] &lt;&lt; 2) &amp; 0xff) | (key _56[6] &gt;&gt; 6);
	key[1] = (key_56[6] &lt;&lt; 1) &amp; 0xff)
	
	des_set_odd_parity(&amp;key);
	des_set_key(&amp;key, ks);
}
</PRE></DIV>
<H3>Keeping the connection alive</H3>
<P>As mentioned above, this scheme authenticates <SPAN style="FONT-STYLE: italic">connections</SPAN>, not requests. This mainfests itself in that the network connection must be kept alive during the second part of the handshake, i.e. between the receiving of the type-2 message from the server (step 4) and the sending of the type-3 message (step 5). Each time the connection is closed this second part (steps 3 through 6) must be repeated over the new connection (i.e. it's not enough to just keep sending the last type-3 message). Also, once the connection is authenticated, the Authorization header need not be sent anymore while the connection stays open, no atter what resource is accessed.<BR><BR>For implementations wishing to work with M$'s software this means that they must make sure they use either HTTP/1.0 keep-alive's or HTTP/1.1 persistent connections, and that they must be prepared to do the second part of the handshake each time the connection was closed and is responed. Server implementations must also make sure that HTTP/1.0 responses contain a Content-length header (as otherwise the connection must be closed after the reponse), and that HTTP/1.1 responses either contain a Content-length header or use the chunked transfer encoding.</P>
<H3>Example</H3>
<P>Here is an actual example of all the message. Assume the host name s "LightCity", the NT domain name is "Ursa-Minor", the username is "Zaphod", the password is "Beeblebrox", and the server sends the nonce "SrvNonce". Then the handshake is:</P>
<DIV style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 4px; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid">
<TABLE style="FONT-SIZE: 10px">
<TBODY>
<TR>
<TD>1:</TD>
<TD>C</TD>
<TD>-&gt;</TD>
<TD>S</TD>
<TD>&nbsp;&nbsp;</TD>
<TD><STRONG>GET...</STRONG></TD></TR>
<TR>
<TD>2:</TD>
<TD>C</TD>
<TD>&lt;-</TD>
<TD>S</TD>
<TD>&nbsp;&nbsp;</TD>
<TD><STRONG>401 Unauthorized</STRONG></TD></TR>
<TR>
<TD colSpan=5>&nbsp;</TD>
<TD><STRONG>WWW-Authenticate: NTLM</STRONG></TD></TR>
<TR>
<TD>3:</TD>
<TD>C</TD>
<TD>-&gt;</TD>
<TD>S</TD>
<TD>&nbsp;&nbsp;</TD>
<TD><STRONG>GET...</STRONG></TD></TR>
<TR>
<TD colSpan=5>&nbsp;</TD>
<TD><STRONG>Authorization: NTLM TlRMTVNTUAABAAAAA7IAAAoACgApAAAACQAJACAAAABMSUdIVENJVFlVUlNBLU1JTk9S</STRONG></TD></TR>
<TR>
<TD>4:</TD>
<TD>C</TD>
<TD>&lt;-</TD>
<TD>S</TD>
<TD>&nbsp;&nbsp;</TD>
<TD><STRONG>401 Unauthorized</STRONG></TD></TR>
<TR>
<TD colSpan=5>&nbsp;</TD>
<TD><STRONG>WWW-Authenticate: NTLM TlRMTVNTUAACAAAAAAAAACgAAAABggAAU3J2Tm9uY2UAAAAAAAAAAA==</STRONG></TD></TR>
<TR>
<TD>5:</TD>
<TD>C</TD>
<TD>-&gt;</TD>
<TD>S</TD>
<TD>&nbsp;&nbsp;</TD>
<TD><STRONG>GET...</STRONG></TD></TR>
<TR>
<TD colSpan=5>&nbsp;</TD>
<TD><STRONG>Authorization: NTLM TlRMTVNTUAADAAAAGAAYAHIAAAAYABgAigAAABQAFABAAAAADAAMAFQAAAASABIAYAAAAAAAAACiAAAAAYIAAFUAUgBTAEEALQBNAEkATgBPAFIAWgBhAHAAaABvAGQATABJAEcASABUAEMASQBUAFkArYfKbe/jRoW5xDxHeoxC1gBmfWiS5+iX4OAN4xBKG/IFPwfH3agtPEia6YnhsADT</STRONG></TD></TR>
<TR>
<TD>6:</TD>
<TD>C</TD>
<TD>&lt;-</TD>
<TD>S</TD>
<TD>&nbsp;&nbsp;</TD>
<TD><STRONG>200 Ok</STRONG></TD></TR></TBODY></TABLE></DIV><BR><BR>
<P>For reference, the intermediate hashed paswords are: </P>
<DIV style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 4px; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid"><PRE style="FONT-SIZE: 10px; FONT-FAMILY: Verdana">lm_hpw(LanManager hashed password): 91 90 16 f6 4e c7 b0 0b a2 35 02 8c a5 0c 7a 03 00 00 00 00 00
nt_hpw(NT hashed password) 8c 1b 59 e3 2e 66 6d ad f1 75 74 5f ad 62 c1 33 00 00 00 00 00
</PRE></DIV>
<H3>Resources</H3>
<UL>
<LI>LM authentication in SMB/CIFS <A href="http://www.ubiqx.org/cifs/SMB.html#SMB.8.3">http://www.ubiqx.org/cifs/SMB.html#SMB.8.3</A> 
<LI>A document on cracking NTLMv2 authentication <A href="http://www.blackhat.com/presentations/win-usa-02/urity-winsec02.ppt">http://www.blackhat.com/presentations/win-usa-02/urity-winsec02.ppt</A> 
<LI>Squid's NTLM authentication project <A href="http://squid.sourceforge.net/ntlm/">http://squid.sourceforge.net/ntlm/</A> 
<LI>Encryption description for Samba <A href="http://de.samba.org/samba/ftp/docs/htmldocs/ENCRYPTION.html">http://de.samba.org/samba/ftp/docs/htmldocs/ENCRYPTION.html</A> 
<LI>Info on the MSIE security hole <A href="http://oliver.efri.hr/~crv/security/bugs/NT/ie6.html">http://oliver.efri.hr/~crv/security/bugs/NT/ie6.html</A> 
<LI>FAQ: NT Cryptographic Password Attacks &amp; Defences <A href="http://www.ntbugtraq.com/default.asp?sid=1&amp;pid=47&amp;aid=17">http://www.ntbugtraq.com/default.asp?sid=1&amp;pid=47&amp;aid=17</A> 
<LI>M$'s hotfix to disable the sending of the LanManager response <A href="ftp://ftp.microsoft.com/bussys/winnt/winnt-public/fixes/usa/NT40/hotfixes-postSP3/lm-fix">ftp://ftp.microsoft.com/bussys/winnt/winnt-public/fixes/usa/NT40/hotfixes-postSP3/lm-fix</A> 
<LI>A description of M$'s hotfix <A href="http://www.tryc.on.ca/archives/bugtraq/1997_3/0070.html">http://www.tryc.on.ca/archives/bugtraq/1997_3/0070.html</A></LI></UL>
<H3>Acknowledgements</H3>
<P>Special thanks to the following people who helped with the collection and debugging of the above information:</P>
<UL>
<LI><A href="mailto:jlennard@dsg.com">Jon Lennard</A> 
<LI><A href="mailto:paul@argo.demon.co.uk">Paul Ashton</A> 
<LI><A href="mailto:samba-bugs@samba.anu.edu.au">Jeremy Allison</A></LI></UL>
<P style="FONT-STYLE: italic">Ronald Tschalär / 17. June 2003 / <A href="http://www.cnweblog.com/alsan/admin/ronald@innovation.ch">ronald@innovation.ch</A>.</P></FONT><img src ="http://www.cnitblog.com/alsan/aggbug/361.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/alsan/" target="_blank">毒菇求Buy</a> 2005-06-12 15:53 <a href="http://www.cnitblog.com/alsan/articles/361.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>