blob: 4ffe2b5dc6d5a826e0900eb673ddff1fd382054e [file] [log] [blame]
Junio C Hamano0df92712011-12-21 22:30:441<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
2 "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
4<head>
Junio C Hamano9d971152012-12-19 00:43:115<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=UTF-8" />
6<meta name="generator" content="AsciiDoc 8.6.8" />
Junio C Hamano0df92712011-12-21 22:30:447<title>credentials API</title>
8<style type="text/css">
Junio C Hamano9d971152012-12-19 00:43:119/* Shared CSS for AsciiDoc xhtml11 and html5 backends */
10
11/* Default font. */
12body {
13 font-family: Georgia,serif;
14}
15
16/* Title font. */
17h1, h2, h3, h4, h5, h6,
18div.title, caption.title,
19thead, p.table.header,
20#toctitle,
21#author, #revnumber, #revdate, #revremark,
22#footer {
23 font-family: Arial,Helvetica,sans-serif;
Junio C Hamano0df92712011-12-21 22:30:4424}
25
26body {
27 margin: 1em 5% 1em 5%;
28}
29
30a {
31 color: blue;
32 text-decoration: underline;
33}
34a:visited {
35 color: fuchsia;
36}
37
38em {
39 font-style: italic;
40 color: navy;
41}
42
43strong {
44 font-weight: bold;
45 color: #083194;
46}
47
Junio C Hamano0df92712011-12-21 22:30:4448h1, h2, h3, h4, h5, h6 {
49 color: #527bbd;
Junio C Hamano0df92712011-12-21 22:30:4450 margin-top: 1.2em;
51 margin-bottom: 0.5em;
52 line-height: 1.3;
53}
54
55h1, h2, h3 {
56 border-bottom: 2px solid silver;
57}
58h2 {
59 padding-top: 0.5em;
60}
61h3 {
62 float: left;
63}
64h3 + * {
65 clear: left;
66}
Junio C Hamano9d971152012-12-19 00:43:1167h5 {
68 font-size: 1.0em;
69}
Junio C Hamano0df92712011-12-21 22:30:4470
71div.sectionbody {
Junio C Hamano0df92712011-12-21 22:30:4472 margin-left: 0;
73}
74
75hr {
76 border: 1px solid silver;
77}
78
79p {
80 margin-top: 0.5em;
81 margin-bottom: 0.5em;
82}
83
84ul, ol, li > p {
85 margin-top: 0;
86}
Junio C Hamano9d971152012-12-19 00:43:1187ul > li { color: #aaa; }
88ul > li > * { color: black; }
Junio C Hamano0df92712011-12-21 22:30:4489
Junio C Hamano9d971152012-12-19 00:43:1190.monospaced, code, pre {
91 font-family: "Courier New", Courier, monospace;
92 font-size: inherit;
93 color: navy;
Junio C Hamano0df92712011-12-21 22:30:4494 padding: 0;
95 margin: 0;
96}
97
Junio C Hamano9d971152012-12-19 00:43:1198
99#author {
Junio C Hamano0df92712011-12-21 22:30:44100 color: #527bbd;
Junio C Hamano0df92712011-12-21 22:30:44101 font-weight: bold;
102 font-size: 1.1em;
103}
Junio C Hamano9d971152012-12-19 00:43:11104#email {
Junio C Hamano0df92712011-12-21 22:30:44105}
Junio C Hamano9d971152012-12-19 00:43:11106#revnumber, #revdate, #revremark {
Junio C Hamano0df92712011-12-21 22:30:44107}
108
Junio C Hamano9d971152012-12-19 00:43:11109#footer {
Junio C Hamano0df92712011-12-21 22:30:44110 font-size: small;
111 border-top: 2px solid silver;
112 padding-top: 0.5em;
113 margin-top: 4.0em;
114}
Junio C Hamano9d971152012-12-19 00:43:11115#footer-text {
Junio C Hamano0df92712011-12-21 22:30:44116 float: left;
117 padding-bottom: 0.5em;
118}
Junio C Hamano9d971152012-12-19 00:43:11119#footer-badges {
Junio C Hamano0df92712011-12-21 22:30:44120 float: right;
121 padding-bottom: 0.5em;
122}
123
Junio C Hamano9d971152012-12-19 00:43:11124#preamble {
Junio C Hamano0df92712011-12-21 22:30:44125 margin-top: 1.5em;
126 margin-bottom: 1.5em;
127}
Junio C Hamano9d971152012-12-19 00:43:11128div.imageblock, div.exampleblock, div.verseblock,
Junio C Hamano0df92712011-12-21 22:30:44129div.quoteblock, div.literalblock, div.listingblock, div.sidebarblock,
130div.admonitionblock {
131 margin-top: 1.0em;
132 margin-bottom: 1.5em;
133}
134div.admonitionblock {
135 margin-top: 2.0em;
136 margin-bottom: 2.0em;
137 margin-right: 10%;
138 color: #606060;
139}
140
141div.content { /* Block element content. */
142 padding: 0;
143}
144
145/* Block element titles. */
146div.title, caption.title {
147 color: #527bbd;
Junio C Hamano0df92712011-12-21 22:30:44148 font-weight: bold;
149 text-align: left;
150 margin-top: 1.0em;
151 margin-bottom: 0.5em;
152}
153div.title + * {
154 margin-top: 0;
155}
156
157td div.title:first-child {
158 margin-top: 0.0em;
159}
160div.content div.title:first-child {
161 margin-top: 0.0em;
162}
163div.content + div.title {
164 margin-top: 0.0em;
165}
166
167div.sidebarblock > div.content {
168 background: #ffffee;
Junio C Hamano9d971152012-12-19 00:43:11169 border: 1px solid #dddddd;
170 border-left: 4px solid #f0f0f0;
Junio C Hamano0df92712011-12-21 22:30:44171 padding: 0.5em;
172}
173
174div.listingblock > div.content {
Junio C Hamano9d971152012-12-19 00:43:11175 border: 1px solid #dddddd;
176 border-left: 5px solid #f0f0f0;
177 background: #f8f8f8;
Junio C Hamano0df92712011-12-21 22:30:44178 padding: 0.5em;
179}
180
181div.quoteblock, div.verseblock {
182 padding-left: 1.0em;
183 margin-left: 1.0em;
184 margin-right: 10%;
Junio C Hamano9d971152012-12-19 00:43:11185 border-left: 5px solid #f0f0f0;
186 color: #888;
Junio C Hamano0df92712011-12-21 22:30:44187}
188
189div.quoteblock > div.attribution {
190 padding-top: 0.5em;
191 text-align: right;
192}
193
Junio C Hamano9d971152012-12-19 00:43:11194div.verseblock > pre.content {
195 font-family: inherit;
196 font-size: inherit;
Junio C Hamano0df92712011-12-21 22:30:44197}
198div.verseblock > div.attribution {
199 padding-top: 0.75em;
200 text-align: left;
201}
202/* DEPRECATED: Pre version 8.2.7 verse style literal block. */
203div.verseblock + div.attribution {
204 text-align: left;
205}
206
207div.admonitionblock .icon {
208 vertical-align: top;
209 font-size: 1.1em;
210 font-weight: bold;
211 text-decoration: underline;
212 color: #527bbd;
213 padding-right: 0.5em;
214}
215div.admonitionblock td.content {
216 padding-left: 0.5em;
217 border-left: 3px solid #dddddd;
218}
219
220div.exampleblock > div.content {
221 border-left: 3px solid #dddddd;
222 padding-left: 0.5em;
223}
224
225div.imageblock div.content { padding-left: 0; }
226span.image img { border-style: none; }
227a.image:visited { color: white; }
228
229dl {
230 margin-top: 0.8em;
231 margin-bottom: 0.8em;
232}
233dt {
234 margin-top: 0.5em;
235 margin-bottom: 0;
236 font-style: normal;
237 color: navy;
238}
239dd > *:first-child {
240 margin-top: 0.1em;
241}
242
243ul, ol {
244 list-style-position: outside;
245}
246ol.arabic {
247 list-style-type: decimal;
248}
249ol.loweralpha {
250 list-style-type: lower-alpha;
251}
252ol.upperalpha {
253 list-style-type: upper-alpha;
254}
255ol.lowerroman {
256 list-style-type: lower-roman;
257}
258ol.upperroman {
259 list-style-type: upper-roman;
260}
261
262div.compact ul, div.compact ol,
263div.compact p, div.compact p,
264div.compact div, div.compact div {
265 margin-top: 0.1em;
266 margin-bottom: 0.1em;
267}
268
Junio C Hamano0df92712011-12-21 22:30:44269tfoot {
270 font-weight: bold;
271}
272td > div.verse {
273 white-space: pre;
274}
Junio C Hamano0df92712011-12-21 22:30:44275
276div.hdlist {
277 margin-top: 0.8em;
278 margin-bottom: 0.8em;
279}
280div.hdlist tr {
281 padding-bottom: 15px;
282}
283dt.hdlist1.strong, td.hdlist1.strong {
284 font-weight: bold;
285}
286td.hdlist1 {
287 vertical-align: top;
288 font-style: normal;
289 padding-right: 0.8em;
290 color: navy;
291}
292td.hdlist2 {
293 vertical-align: top;
294}
295div.hdlist.compact tr {
296 margin: 0;
297 padding-bottom: 0;
298}
299
300.comment {
301 background: yellow;
302}
303
304.footnote, .footnoteref {
305 font-size: 0.8em;
306}
307
308span.footnote, span.footnoteref {
309 vertical-align: super;
310}
311
312#footnotes {
313 margin: 20px 0 20px 0;
314 padding: 7px 0 0 0;
315}
316
317#footnotes div.footnote {
318 margin: 0 0 5px 0;
319}
320
321#footnotes hr {
322 border: none;
323 border-top: 1px solid silver;
324 height: 1px;
325 text-align: left;
326 margin-left: 0;
327 width: 20%;
328 min-width: 100px;
329}
330
Junio C Hamano9d971152012-12-19 00:43:11331div.colist td {
332 padding-right: 0.5em;
333 padding-bottom: 0.3em;
334 vertical-align: top;
335}
336div.colist td img {
337 margin-top: 0.3em;
Junio C Hamano0df92712011-12-21 22:30:44338}
339
Junio C Hamano9d971152012-12-19 00:43:11340@media print {
341 #footer-badges { display: none; }
342}
343
344#toc {
Junio C Hamano0df92712011-12-21 22:30:44345 margin-bottom: 2.5em;
346}
347
Junio C Hamano9d971152012-12-19 00:43:11348#toctitle {
Junio C Hamano0df92712011-12-21 22:30:44349 color: #527bbd;
Junio C Hamano0df92712011-12-21 22:30:44350 font-size: 1.1em;
351 font-weight: bold;
352 margin-top: 1.0em;
353 margin-bottom: 0.1em;
354}
355
Junio C Hamano9d971152012-12-19 00:43:11356div.toclevel0, div.toclevel1, div.toclevel2, div.toclevel3, div.toclevel4 {
Junio C Hamano0df92712011-12-21 22:30:44357 margin-top: 0;
358 margin-bottom: 0;
359}
360div.toclevel2 {
361 margin-left: 2em;
362 font-size: 0.9em;
363}
364div.toclevel3 {
365 margin-left: 4em;
366 font-size: 0.9em;
367}
368div.toclevel4 {
369 margin-left: 6em;
370 font-size: 0.9em;
371}
Junio C Hamano0df92712011-12-21 22:30:44372
Junio C Hamano9d971152012-12-19 00:43:11373span.aqua { color: aqua; }
374span.black { color: black; }
375span.blue { color: blue; }
376span.fuchsia { color: fuchsia; }
377span.gray { color: gray; }
378span.green { color: green; }
379span.lime { color: lime; }
380span.maroon { color: maroon; }
381span.navy { color: navy; }
382span.olive { color: olive; }
383span.purple { color: purple; }
384span.red { color: red; }
385span.silver { color: silver; }
386span.teal { color: teal; }
387span.white { color: white; }
388span.yellow { color: yellow; }
389
390span.aqua-background { background: aqua; }
391span.black-background { background: black; }
392span.blue-background { background: blue; }
393span.fuchsia-background { background: fuchsia; }
394span.gray-background { background: gray; }
395span.green-background { background: green; }
396span.lime-background { background: lime; }
397span.maroon-background { background: maroon; }
398span.navy-background { background: navy; }
399span.olive-background { background: olive; }
400span.purple-background { background: purple; }
401span.red-background { background: red; }
402span.silver-background { background: silver; }
403span.teal-background { background: teal; }
404span.white-background { background: white; }
405span.yellow-background { background: yellow; }
406
407span.big { font-size: 2em; }
408span.small { font-size: 0.6em; }
409
410span.underline { text-decoration: underline; }
411span.overline { text-decoration: overline; }
412span.line-through { text-decoration: line-through; }
413
414div.unbreakable { page-break-inside: avoid; }
415
416
417/*
418 * xhtml11 specific
419 *
420 * */
421
422div.tableblock {
423 margin-top: 1.0em;
424 margin-bottom: 1.5em;
Junio C Hamano0df92712011-12-21 22:30:44425}
Junio C Hamano9d971152012-12-19 00:43:11426div.tableblock > table {
427 border: 3px solid #527bbd;
428}
429thead, p.table.header {
Junio C Hamano0df92712011-12-21 22:30:44430 font-weight: bold;
Junio C Hamano9d971152012-12-19 00:43:11431 color: #527bbd;
432}
433p.table {
434 margin-top: 0;
435}
436/* Because the table frame attribute is overriden by CSS in most browsers. */
437div.tableblock > table[frame="void"] {
438 border-style: none;
439}
440div.tableblock > table[frame="hsides"] {
441 border-left-style: none;
442 border-right-style: none;
443}
444div.tableblock > table[frame="vsides"] {
445 border-top-style: none;
446 border-bottom-style: none;
Junio C Hamano0df92712011-12-21 22:30:44447}
448
Junio C Hamano9d971152012-12-19 00:43:11449
450/*
451 * html5 specific
452 *
453 * */
454
455table.tableblock {
456 margin-top: 1.0em;
457 margin-bottom: 1.5em;
458}
459thead, p.tableblock.header {
460 font-weight: bold;
461 color: #527bbd;
462}
463p.tableblock {
464 margin-top: 0;
465}
466table.tableblock {
467 border-width: 3px;
468 border-spacing: 0px;
469 border-style: solid;
470 border-color: #527bbd;
471 border-collapse: collapse;
472}
473th.tableblock, td.tableblock {
474 border-width: 1px;
475 padding: 4px;
476 border-style: solid;
477 border-color: #527bbd;
Junio C Hamano0df92712011-12-21 22:30:44478}
479
Junio C Hamano9d971152012-12-19 00:43:11480table.tableblock.frame-topbot {
481 border-left-style: hidden;
482 border-right-style: hidden;
483}
484table.tableblock.frame-sides {
485 border-top-style: hidden;
486 border-bottom-style: hidden;
487}
488table.tableblock.frame-none {
489 border-style: hidden;
490}
491
492th.tableblock.halign-left, td.tableblock.halign-left {
493 text-align: left;
494}
495th.tableblock.halign-center, td.tableblock.halign-center {
496 text-align: center;
497}
498th.tableblock.halign-right, td.tableblock.halign-right {
Junio C Hamano0df92712011-12-21 22:30:44499 text-align: right;
500}
501
Junio C Hamano9d971152012-12-19 00:43:11502th.tableblock.valign-top, td.tableblock.valign-top {
503 vertical-align: top;
Junio C Hamano0df92712011-12-21 22:30:44504}
Junio C Hamano9d971152012-12-19 00:43:11505th.tableblock.valign-middle, td.tableblock.valign-middle {
506 vertical-align: middle;
507}
508th.tableblock.valign-bottom, td.tableblock.valign-bottom {
509 vertical-align: bottom;
Junio C Hamano0df92712011-12-21 22:30:44510}
511
Junio C Hamano9d971152012-12-19 00:43:11512
513/*
514 * manpage specific
515 *
516 * */
517
518body.manpage h1 {
519 padding-top: 0.5em;
520 padding-bottom: 0.5em;
521 border-top: 2px solid silver;
522 border-bottom: 2px solid silver;
523}
524body.manpage h2 {
525 border-style: none;
526}
527body.manpage div.sectionbody {
528 margin-left: 3em;
Junio C Hamano0df92712011-12-21 22:30:44529}
530
Junio C Hamano9d971152012-12-19 00:43:11531@media print {
532 body.manpage div#toc { display: none; }
533}
534
535
Junio C Hamano0df92712011-12-21 22:30:44536</style>
537<script type="text/javascript">
538/*<![CDATA[*/
Junio C Hamano0df92712011-12-21 22:30:44539var asciidoc = { // Namespace.
540
541/////////////////////////////////////////////////////////////////////
542// Table Of Contents generator
543/////////////////////////////////////////////////////////////////////
544
545/* Author: Mihai Bazon, September 2002
546 * http://students.infoiasi.ro/~mishoo
547 *
548 * Table Of Content generator
549 * Version: 0.4
550 *
551 * Feel free to use this script under the terms of the GNU General Public
552 * License, as long as you do not remove or alter this notice.
553 */
554
555 /* modified by Troy D. Hanson, September 2006. License: GPL */
556 /* modified by Stuart Rackham, 2006, 2009. License: GPL */
557
558// toclevels = 1..4.
559toc: function (toclevels) {
560
561 function getText(el) {
562 var text = "";
563 for (var i = el.firstChild; i != null; i = i.nextSibling) {
564 if (i.nodeType == 3 /* Node.TEXT_NODE */) // IE doesn't speak constants.
565 text += i.data;
566 else if (i.firstChild != null)
567 text += getText(i);
568 }
569 return text;
570 }
571
572 function TocEntry(el, text, toclevel) {
573 this.element = el;
574 this.text = text;
575 this.toclevel = toclevel;
576 }
577
578 function tocEntries(el, toclevels) {
579 var result = new Array;
Junio C Hamano9d971152012-12-19 00:43:11580 var re = new RegExp('[hH]([1-'+(toclevels+1)+'])');
Junio C Hamano0df92712011-12-21 22:30:44581 // Function that scans the DOM tree for header elements (the DOM2
582 // nodeIterator API would be a better technique but not supported by all
583 // browsers).
584 var iterate = function (el) {
585 for (var i = el.firstChild; i != null; i = i.nextSibling) {
586 if (i.nodeType == 1 /* Node.ELEMENT_NODE */) {
587 var mo = re.exec(i.tagName);
588 if (mo && (i.getAttribute("class") || i.getAttribute("className")) != "float") {
589 result[result.length] = new TocEntry(i, getText(i), mo[1]-1);
590 }
591 iterate(i);
592 }
593 }
594 }
595 iterate(el);
596 return result;
597 }
598
599 var toc = document.getElementById("toc");
Junio C Hamano9d971152012-12-19 00:43:11600 if (!toc) {
601 return;
602 }
603
604 // Delete existing TOC entries in case we're reloading the TOC.
605 var tocEntriesToRemove = [];
606 var i;
607 for (i = 0; i < toc.childNodes.length; i++) {
608 var entry = toc.childNodes[i];
609 if (entry.nodeName.toLowerCase() == 'div'
610 && entry.getAttribute("class")
611 && entry.getAttribute("class").match(/^toclevel/))
612 tocEntriesToRemove.push(entry);
613 }
614 for (i = 0; i < tocEntriesToRemove.length; i++) {
615 toc.removeChild(tocEntriesToRemove[i]);
616 }
617
618 // Rebuild TOC entries.
Junio C Hamano0df92712011-12-21 22:30:44619 var entries = tocEntries(document.getElementById("content"), toclevels);
620 for (var i = 0; i < entries.length; ++i) {
621 var entry = entries[i];
622 if (entry.element.id == "")
623 entry.element.id = "_toc_" + i;
624 var a = document.createElement("a");
625 a.href = "#" + entry.element.id;
626 a.appendChild(document.createTextNode(entry.text));
627 var div = document.createElement("div");
628 div.appendChild(a);
629 div.className = "toclevel" + entry.toclevel;
630 toc.appendChild(div);
631 }
632 if (entries.length == 0)
633 toc.parentNode.removeChild(toc);
634},
635
636
637/////////////////////////////////////////////////////////////////////
638// Footnotes generator
639/////////////////////////////////////////////////////////////////////
640
641/* Based on footnote generation code from:
642 * http://www.brandspankingnew.net/archive/2005/07/format_footnote.html
643 */
644
645footnotes: function () {
Junio C Hamano9d971152012-12-19 00:43:11646 // Delete existing footnote entries in case we're reloading the footnodes.
647 var i;
Junio C Hamano0df92712011-12-21 22:30:44648 var noteholder = document.getElementById("footnotes");
Junio C Hamano9d971152012-12-19 00:43:11649 if (!noteholder) {
650 return;
651 }
652 var entriesToRemove = [];
653 for (i = 0; i < noteholder.childNodes.length; i++) {
654 var entry = noteholder.childNodes[i];
655 if (entry.nodeName.toLowerCase() == 'div' && entry.getAttribute("class") == "footnote")
656 entriesToRemove.push(entry);
657 }
658 for (i = 0; i < entriesToRemove.length; i++) {
659 noteholder.removeChild(entriesToRemove[i]);
660 }
661
662 // Rebuild footnote entries.
663 var cont = document.getElementById("content");
Junio C Hamano0df92712011-12-21 22:30:44664 var spans = cont.getElementsByTagName("span");
665 var refs = {};
666 var n = 0;
667 for (i=0; i<spans.length; i++) {
668 if (spans[i].className == "footnote") {
669 n++;
Junio C Hamano9d971152012-12-19 00:43:11670 var note = spans[i].getAttribute("data-note");
671 if (!note) {
672 // Use [\s\S] in place of . so multi-line matches work.
673 // Because JavaScript has no s (dotall) regex flag.
674 note = spans[i].innerHTML.match(/\s*\[([\s\S]*)]\s*/)[1];
675 spans[i].innerHTML =
676 "[<a id='_footnoteref_" + n + "' href='#_footnote_" + n +
677 "' title='View footnote' class='footnote'>" + n + "</a>]";
678 spans[i].setAttribute("data-note", note);
679 }
Junio C Hamano0df92712011-12-21 22:30:44680 noteholder.innerHTML +=
681 "<div class='footnote' id='_footnote_" + n + "'>" +
682 "<a href='#_footnoteref_" + n + "' title='Return to text'>" +
683 n + "</a>. " + note + "</div>";
Junio C Hamano0df92712011-12-21 22:30:44684 var id =spans[i].getAttribute("id");
685 if (id != null) refs["#"+id] = n;
686 }
687 }
688 if (n == 0)
689 noteholder.parentNode.removeChild(noteholder);
690 else {
691 // Process footnoterefs.
692 for (i=0; i<spans.length; i++) {
693 if (spans[i].className == "footnoteref") {
694 var href = spans[i].getElementsByTagName("a")[0].getAttribute("href");
695 href = href.match(/#.*/)[0]; // Because IE return full URL.
696 n = refs[href];
697 spans[i].innerHTML =
698 "[<a href='#_footnote_" + n +
699 "' title='View footnote' class='footnote'>" + n + "</a>]";
700 }
701 }
702 }
Junio C Hamano9d971152012-12-19 00:43:11703},
704
705install: function(toclevels) {
706 var timerId;
707
708 function reinstall() {
709 asciidoc.footnotes();
710 if (toclevels) {
711 asciidoc.toc(toclevels);
712 }
713 }
714
715 function reinstallAndRemoveTimer() {
716 clearInterval(timerId);
717 reinstall();
718 }
719
720 timerId = setInterval(reinstall, 500);
721 if (document.addEventListener)
722 document.addEventListener("DOMContentLoaded", reinstallAndRemoveTimer, false);
723 else
724 window.onload = reinstallAndRemoveTimer;
Junio C Hamano0df92712011-12-21 22:30:44725}
726
727}
Junio C Hamano9d971152012-12-19 00:43:11728asciidoc.install();
Junio C Hamano0df92712011-12-21 22:30:44729/*]]>*/
730</script>
731</head>
Junio C Hamano9d971152012-12-19 00:43:11732<body class="article">
Junio C Hamano0df92712011-12-21 22:30:44733<div id="header">
734<h1>credentials API</h1>
735</div>
736<div id="content">
737<div id="preamble">
738<div class="sectionbody">
739<div class="paragraph"><p>The credentials API provides an abstracted way of gathering username and
740password credentials from the user (even though credentials in the wider
741world can take many forms, in this document the word "credential" always
742refers to a username and password pair).</p></div>
Junio C Hamano022bd342012-06-07 20:15:35743<div class="paragraph"><p>This document describes two interfaces: the C API that the credential
Junio C Hamano076ffcc2013-02-06 05:13:21744subsystem provides to the rest of Git, and the protocol that Git uses to
Junio C Hamano022bd342012-06-07 20:15:35745communicate with system-specific "credential helpers". If you are
Junio C Hamano076ffcc2013-02-06 05:13:21746writing Git code that wants to look up or prompt for credentials, see
Junio C Hamano022bd342012-06-07 20:15:35747the section "C API" below. If you want to write your own helper, see
748the section on "Credential Helpers" below.</p></div>
Junio C Hamano0df92712011-12-21 22:30:44749</div>
750</div>
Junio C Hamano9d971152012-12-19 00:43:11751<div class="sect1">
Junio C Hamano022bd342012-06-07 20:15:35752<h2 id="_typical_setup">Typical setup</h2>
Junio C Hamano0df92712011-12-21 22:30:44753<div class="sectionbody">
Junio C Hamano022bd342012-06-07 20:15:35754<div class="listingblock">
755<div class="content">
Junio C Hamano9d971152012-12-19 00:43:11756<pre><code>+-----------------------+
Junio C Hamano076ffcc2013-02-06 05:13:21757| Git code (C) |--- to server requiring ---&gt;
Junio C Hamano022bd342012-06-07 20:15:35758| | authentication
759|.......................|
760| C credential API |--- prompt ---&gt; User
761+-----------------------+
762 ^ |
763 | pipe |
764 | v
765+-----------------------+
Junio C Hamano076ffcc2013-02-06 05:13:21766| Git credential helper |
Junio C Hamano9d971152012-12-19 00:43:11767+-----------------------+</code></pre>
Junio C Hamano022bd342012-06-07 20:15:35768</div></div>
Junio C Hamano076ffcc2013-02-06 05:13:21769<div class="paragraph"><p>The Git code (typically a remote-helper) will call the C API to obtain
Junio C Hamano022bd342012-06-07 20:15:35770credential data like a login/password pair (credential_fill). The
771API will itself call a remote helper (e.g. "git credential-cache" or
772"git credential-store") that may retrieve credential data from a
773store. If the credential helper cannot find the information, the C API
774will prompt the user. Then, the caller of the API takes care of
775contacting the server, and does the actual authentication.</p></div>
776</div>
Junio C Hamano9d971152012-12-19 00:43:11777</div>
778<div class="sect1">
Junio C Hamano022bd342012-06-07 20:15:35779<h2 id="_c_api">C API</h2>
780<div class="sectionbody">
Junio C Hamano076ffcc2013-02-06 05:13:21781<div class="paragraph"><p>The credential C API is meant to be called by Git code which needs to
Junio C Hamano022bd342012-06-07 20:15:35782acquire or store a credential. It is centered around an object
783representing a single credential and provides three basic operations:
784fill (acquire credentials by calling helpers and/or prompting the user),
785approve (mark a credential as successfully used so that it can be stored
786for later use), and reject (mark a credential as unsuccessful so that it
787can be erased from any persistent storage).</p></div>
Junio C Hamano9d971152012-12-19 00:43:11788<div class="sect2">
789<h3 id="_data_structures">Data Structures</h3>
Junio C Hamano0df92712011-12-21 22:30:44790<div class="dlist"><dl>
791<dt class="hdlist1">
Junio C Hamano9d971152012-12-19 00:43:11792<code>struct credential</code>
Junio C Hamano0df92712011-12-21 22:30:44793</dt>
794<dd>
795<p>
796 This struct represents a single username/password combination
797 along with any associated context. All string fields should be
798 heap-allocated (or NULL if they are not known or not applicable).
799 The meaning of the individual context fields is the same as
800 their counterparts in the helper protocol; see the section below
801 for a description of each field.
802</p>
Junio C Hamano9d971152012-12-19 00:43:11803<div class="paragraph"><p>The <code>helpers</code> member of the struct is a <code>string_list</code> of helpers. Each
Junio C Hamano0df92712011-12-21 22:30:44804string specifies an external helper which will be run, in order, to
805either acquire or store credentials. See the section on credential
Junio C Hamano9f9ed8b2012-06-13 07:21:43806helpers below. This list is filled-in by the API functions
807according to the corresponding configuration variables before
808consulting helpers, so there usually is no need for a caller to
809modify the helpers field at all.</p></div>
Junio C Hamano9d971152012-12-19 00:43:11810<div class="paragraph"><p>This struct should always be initialized with <code>CREDENTIAL_INIT</code> or
811<code>credential_init</code>.</p></div>
Junio C Hamano0df92712011-12-21 22:30:44812</dd>
813</dl></div>
Junio C Hamano9d971152012-12-19 00:43:11814</div>
815<div class="sect2">
816<h3 id="_functions">Functions</h3>
Junio C Hamano0df92712011-12-21 22:30:44817<div class="dlist"><dl>
818<dt class="hdlist1">
Junio C Hamano9d971152012-12-19 00:43:11819<code>credential_init</code>
Junio C Hamano0df92712011-12-21 22:30:44820</dt>
821<dd>
822<p>
823 Initialize a credential structure, setting all fields to empty.
824</p>
825</dd>
826<dt class="hdlist1">
Junio C Hamano9d971152012-12-19 00:43:11827<code>credential_clear</code>
Junio C Hamano0df92712011-12-21 22:30:44828</dt>
829<dd>
830<p>
831 Free any resources associated with the credential structure,
832 returning it to a pristine initialized state.
833</p>
834</dd>
835<dt class="hdlist1">
Junio C Hamano9d971152012-12-19 00:43:11836<code>credential_fill</code>
Junio C Hamano0df92712011-12-21 22:30:44837</dt>
838<dd>
839<p>
840 Instruct the credential subsystem to fill the username and
841 password fields of the passed credential struct by first
842 consulting helpers, then asking the user. After this function
843 returns, the username and password fields of the credential are
844 guaranteed to be non-NULL. If an error occurs, the function will
845 die().
846</p>
847</dd>
848<dt class="hdlist1">
Junio C Hamano9d971152012-12-19 00:43:11849<code>credential_reject</code>
Junio C Hamano0df92712011-12-21 22:30:44850</dt>
851<dd>
852<p>
853 Inform the credential subsystem that the provided credentials
854 have been rejected. This will cause the credential subsystem to
855 notify any helpers of the rejection (which allows them, for
856 example, to purge the invalid credentials from storage). It
857 will also free() the username and password fields of the
858 credential and set them to NULL (readying the credential for
Junio C Hamano9d971152012-12-19 00:43:11859 another call to <code>credential_fill</code>). Any errors from helpers are
Junio C Hamano0df92712011-12-21 22:30:44860 ignored.
861</p>
862</dd>
863<dt class="hdlist1">
Junio C Hamano9d971152012-12-19 00:43:11864<code>credential_approve</code>
Junio C Hamano0df92712011-12-21 22:30:44865</dt>
866<dd>
867<p>
868 Inform the credential subsystem that the provided credentials
869 were successfully used for authentication. This will cause the
870 credential subsystem to notify any helpers of the approval, so
871 that they may store the result to be used again. Any errors
872 from helpers are ignored.
873</p>
874</dd>
875<dt class="hdlist1">
Junio C Hamano9d971152012-12-19 00:43:11876<code>credential_from_url</code>
Junio C Hamano0df92712011-12-21 22:30:44877</dt>
878<dd>
879<p>
880 Parse a URL into broken-down credential fields.
881</p>
882</dd>
883</dl></div>
Junio C Hamano9d971152012-12-19 00:43:11884</div>
885<div class="sect2">
886<h3 id="_example">Example</h3>
Junio C Hamano0df92712011-12-21 22:30:44887<div class="paragraph"><p>The example below shows how the functions of the credential API could be
888used to login to a fictitious "foo" service on a remote host:</p></div>
889<div class="listingblock">
890<div class="content">
Junio C Hamano9d971152012-12-19 00:43:11891<pre><code>int foo_login(struct foo_connection *f)
Junio C Hamano0df92712011-12-21 22:30:44892{
893 int status;
894 /*
895 * Create a credential with some context; we don't yet know the
896 * username or password.
897 */
898
899 struct credential c = CREDENTIAL_INIT;
900 c.protocol = xstrdup("foo");
901 c.host = xstrdup(f-&gt;hostname);
902
903 /*
904 * Fill in the username and password fields by contacting
905 * helpers and/or asking the user. The function will die if it
906 * fails.
907 */
908 credential_fill(&amp;c);
909
910 /*
911 * Otherwise, we have a username and password. Try to use it.
912 */
913 status = send_foo_login(f, c.username, c.password);
914 switch (status) {
915 case FOO_OK:
916 /* It worked. Store the credential for later use. */
917 credential_accept(&amp;c);
918 break;
919 case FOO_BAD_LOGIN:
920 /* Erase the credential from storage so we don't try it
921 * again. */
922 credential_reject(&amp;c);
923 break;
924 default:
925 /*
Junio C Hamanoa080bc32013-04-12 21:33:01926 * Some other error occurred. We don't know if the
Junio C Hamano0df92712011-12-21 22:30:44927 * credential is good or bad, so report nothing to the
928 * credential subsystem.
929 */
930 }
931
932 /* Free any associated resources. */
933 credential_clear(&amp;c);
934
935 return status;
Junio C Hamano9d971152012-12-19 00:43:11936}</code></pre>
Junio C Hamano0df92712011-12-21 22:30:44937</div></div>
938</div>
Junio C Hamano9d971152012-12-19 00:43:11939</div>
940</div>
941<div class="sect1">
Junio C Hamano0df92712011-12-21 22:30:44942<h2 id="_credential_helpers">Credential Helpers</h2>
943<div class="sectionbody">
Junio C Hamano076ffcc2013-02-06 05:13:21944<div class="paragraph"><p>Credential helpers are programs executed by Git to fetch or save
Junio C Hamano0df92712011-12-21 22:30:44945credentials from and to long-term storage (where "long-term" is simply
Junio C Hamano076ffcc2013-02-06 05:13:21946longer than a single Git process; e.g., credentials may be stored
Junio C Hamano0df92712011-12-21 22:30:44947in-memory for a few minutes, or indefinitely on disk).</p></div>
Junio C Hamano022bd342012-06-07 20:15:35948<div class="paragraph"><p>Each helper is specified by a single string in the configuration
Junio C Hamano9d971152012-12-19 00:43:11949variable <code>credential.helper</code> (and others, see <a href="../git-config.html">git-config(1)</a>).
Junio C Hamano076ffcc2013-02-06 05:13:21950The string is transformed by Git into a command to be executed using
Junio C Hamano022bd342012-06-07 20:15:35951these rules:</p></div>
Junio C Hamano0df92712011-12-21 22:30:44952<div class="olist arabic"><ol class="arabic">
953<li>
954<p>
955If the helper string begins with "!", it is considered a shell
956 snippet, and everything after the "!" becomes the command.
957</p>
958</li>
959<li>
960<p>
961Otherwise, if the helper string begins with an absolute path, the
962 verbatim helper string becomes the command.
963</p>
964</li>
965<li>
966<p>
967Otherwise, the string "git credential-" is prepended to the helper
968 string, and the result becomes the command.
969</p>
970</li>
971</ol></div>
972<div class="paragraph"><p>The resulting command then has an "operation" argument appended to it
973(see below for details), and the result is executed by the shell.</p></div>
974<div class="paragraph"><p>Here are some example specifications:</p></div>
975<div class="listingblock">
976<div class="content">
Junio C Hamano9d971152012-12-19 00:43:11977<pre><code># run "git credential-foo"
Junio C Hamano0df92712011-12-21 22:30:44978foo
979
980# same as above, but pass an argument to the helper
981foo --bar=baz
982
983# the arguments are parsed by the shell, so use shell
984# quoting if necessary
985foo --bar="whitespace arg"
986
987# you can also use an absolute path, which will not use the git wrapper
988/path/to/my/helper --with-arguments
989
990# or you can specify your own shell snippet
Junio C Hamano9d971152012-12-19 00:43:11991!f() { echo "password=`cat $HOME/.secret`"; }; f</code></pre>
Junio C Hamano0df92712011-12-21 22:30:44992</div></div>
993<div class="paragraph"><p>Generally speaking, rule (3) above is the simplest for users to specify.
994Authors of credential helpers should make an effort to assist their
995users by naming their program "git-credential-$NAME", and putting it in
996the $PATH or $GIT_EXEC_PATH during installation, which will allow a user
Junio C Hamano9d971152012-12-19 00:43:11997to enable it with <code>git config credential.helper $NAME</code>.</p></div>
Junio C Hamano0df92712011-12-21 22:30:44998<div class="paragraph"><p>When a helper is executed, it will have one "operation" argument
999appended to its command line, which is one of:</p></div>
1000<div class="dlist"><dl>
1001<dt class="hdlist1">
Junio C Hamano9d971152012-12-19 00:43:111002<code>get</code>
Junio C Hamano0df92712011-12-21 22:30:441003</dt>
1004<dd>
1005<p>
1006 Return a matching credential, if any exists.
1007</p>
1008</dd>
1009<dt class="hdlist1">
Junio C Hamano9d971152012-12-19 00:43:111010<code>store</code>
Junio C Hamano0df92712011-12-21 22:30:441011</dt>
1012<dd>
1013<p>
1014 Store the credential, if applicable to the helper.
1015</p>
1016</dd>
1017<dt class="hdlist1">
Junio C Hamano9d971152012-12-19 00:43:111018<code>erase</code>
Junio C Hamano0df92712011-12-21 22:30:441019</dt>
1020<dd>
1021<p>
1022 Remove a matching credential, if any, from the helper&#8217;s storage.
1023</p>
1024</dd>
1025</dl></div>
1026<div class="paragraph"><p>The details of the credential will be provided on the helper&#8217;s stdin
Junio C Hamano8edb4c72012-07-09 20:33:551027stream. The exact format is the same as the input/output format of the
Junio C Hamano9d971152012-12-19 00:43:111028<code>git credential</code> plumbing command (see the section <code>INPUT/OUTPUT
1029FORMAT</code> in <a href="../git-credential.html">git-credential(7)</a> for a detailed specification).</p></div>
1030<div class="paragraph"><p>For a <code>get</code> operation, the helper should produce a list of attributes
Junio C Hamano0df92712011-12-21 22:30:441031on stdout in the same format. A helper is free to produce a subset, or
1032even no values at all if it has nothing useful to provide. Any provided
Junio C Hamano076ffcc2013-02-06 05:13:211033attributes will overwrite those already known about by Git.</p></div>
Junio C Hamano9d971152012-12-19 00:43:111034<div class="paragraph"><p>For a <code>store</code> or <code>erase</code> operation, the helper&#8217;s output is ignored.
Junio C Hamano0df92712011-12-21 22:30:441035If it fails to perform the requested operation, it may complain to
1036stderr to inform the user. If it does not support the requested
1037operation (e.g., a read-only store), it should silently ignore the
1038request.</p></div>
1039<div class="paragraph"><p>If a helper receives any other operation, it should silently ignore the
1040request. This leaves room for future operations to be added (older
1041helpers will just ignore the new requests).</p></div>
1042</div>
Junio C Hamano9d971152012-12-19 00:43:111043</div>
1044<div class="sect1">
Junio C Hamano022bd342012-06-07 20:15:351045<h2 id="_see_also">See also</h2>
1046<div class="sectionbody">
Junio C Hamano719b8a32012-06-08 18:40:531047<div class="paragraph"><p><a href="../gitcredentials.html">gitcredentials(7)</a></p></div>
Junio C Hamano9d971152012-12-19 00:43:111048<div class="paragraph"><p><a href="../git-config.html">git-config(5)</a> (See configuration variables <code>credential.*</code>)</p></div>
1049</div>
Junio C Hamano022bd342012-06-07 20:15:351050</div>
Junio C Hamano0df92712011-12-21 22:30:441051</div>
1052<div id="footnotes"><hr /></div>
1053<div id="footer">
1054<div id="footer-text">
Junio C Hamanoa080bc32013-04-12 21:33:011055Last updated 2013-04-12 14:32:32 PDT
Junio C Hamano0df92712011-12-21 22:30:441056</div>
1057</div>
1058</body>
1059</html>