checked in design document
[sfa.git] / docs / Geniwrapper_Design_Docu.html
1
2 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
3
4 <html>
5
6
7 <head>
8 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
9
10 <base target="_top">
11
12 <style type="text/css">
13
14
15 /* default css */
16
17 table {
18   font-size: 1em;
19   line-height: inherit;
20 }
21
22
23 tr {
24   
25   text-align: left;
26   
27 }
28
29
30 div, address, ol, ul, li, option, select { 
31   margin-top: 0px;
32   margin-bottom: 0px;
33 }
34
35 p {
36   margin: 0px;
37 }
38
39 body {
40   margin: 6px;
41   padding: 0px;
42   font-family: Verdana, sans-serif;
43   font-size: 10pt;
44   background-color: #ffffff;
45 }
46
47
48 img {
49   -moz-force-broken-image-icon: 1;
50 }
51
52 @media screen {
53   html.pageview {
54     background-color: #f3f3f3 !important;
55   }
56
57   
58     
59   body { 
60     min-height: 1100px; 
61   }
62   * html body { 
63     height: 1100px; 
64   }
65   .pageview body {
66     border-top: 1px solid #ccc;
67     border-left: 1px solid #ccc;
68     border-right: 2px solid #bbb;
69     border-bottom: 2px solid #bbb;
70     width: 648px !important;
71     margin: 15px auto 25px;
72     padding: 40px 50px; 
73   }
74   /* IE6 */
75   * html {
76     overflow-y: scroll;
77   }
78   * html.pageview body {
79     overflow-x: auto;
80   }
81   /* Prevent repaint errors when scrolling in Safari. This "Star-7" css hack
82      targets Safari 3.1, but not WebKit nightlies and presumably Safari 4.
83      That's OK because this bug is fixed in WebKit nightlies/Safari 4 :-). */
84   html*#wys_frame::before {
85     content: '\A0';
86     position: fixed;
87     overflow: hidden;
88     width: 0;
89     height: 0;
90     top: 0;
91     left: 0;
92   }
93   
94   
95
96   
97
98
99   
100   .br_fix br:not(:-moz-last-node):not(:-moz-first-node) {
101     
102     position:relative;
103     
104     left: -1ex
105     
106   }
107   
108   .br_fix br+br {
109     position: static !important
110   }
111 }
112
113 h6 { font-size: 8pt }
114 h5 { font-size: 8pt }
115 h4 { font-size: 10pt }
116 h3 { font-size: 12pt }
117 h2 { font-size: 14pt }
118 h1 { font-size: 18pt }
119
120 blockquote {padding: 10px; border: 1px #DDD dashed }
121
122 a img {border: 0}
123
124 .pb {
125   border-width: 0;
126   page-break-after: always;
127   /* We don't want this to be resizeable, so enforce a width and height
128      using !important */
129   height: 1px !important;
130   width: 100% !important;
131 }
132
133 .editor .pb {
134   border-top: 1px dashed #C0C0C0;
135   border-bottom: 1px dashed #C0C0C0;
136 }
137
138 div.google_header, div.google_footer {
139   position: relative;
140   margin-top: 1em;
141   margin-bottom: 1em;
142 }
143
144
145 /* Table of contents */
146 .editor div.writely-toc {
147   background-color: #f3f3f3;
148   border: 1px solid #ccc;
149 }
150 .writely-toc > ol {
151   padding-left: 3em;
152   font-weight: bold;
153 }
154 ol.writely-toc-subheading {
155   padding-left: 1em;
156   font-weight: normal;
157 }
158 /* IE6 only */
159 * html writely-toc ol {
160   list-style-position: inside;
161 }
162 .writely-toc-none {
163   list-style-type: none;
164 }
165 .writely-toc-decimal {
166   list-style-type: decimal;
167 }
168 .writely-toc-upper-alpha {
169   list-style-type: upper-alpha;
170 }
171 .writely-toc-lower-alpha {
172   list-style-type: lower-alpha;
173 }
174 .writely-toc-upper-roman {
175   list-style-type: upper-roman;
176 }
177 .writely-toc-lower-roman {
178   list-style-type: lower-roman;
179 }
180 .writely-toc-disc {
181   list-style-type: disc;
182 }
183
184 /* end default css */
185
186
187   /* default print css */
188   
189   @media print {
190     body { 
191       padding: 0; 
192       margin: 0; 
193     }
194
195     div.google_header, div.google_footer {
196       display: block;
197       min-height: 0;
198       border: none;
199     }
200
201     div.google_header {
202       flow: static(header);
203     }
204
205     /* used to insert page numbers */
206     div.google_header::before, div.google_footer::before {
207       position: absolute;
208       top: 0;
209     }
210
211     div.google_footer {
212       flow: static(footer);
213     }
214
215     /* always consider this element at the start of the doc */
216     div#google_footer {
217       flow: static(footer, start);
218     }
219
220     span.google_pagenumber {
221       content: counter(page);
222     }
223
224     span.google_pagecount {
225       content: counter(pages);
226     }
227
228
229     callout.google_footnote {
230       
231       display: prince-footnote;
232       footnote-style-position: inside;
233       /* These styles keep the footnote from taking on the style of the text
234          surrounding the footnote marker. They can be overridden in the
235          document CSS. */
236       color: #000;
237       font-family: Verdana;
238       font-size: 10.0pt;
239       font-weight: normal;
240     }
241
242     /* Table of contents */
243     #WritelyTableOfContents a::after {
244       content: leader('.') target-counter(attr(href), page);
245     }
246
247     #WritelyTableOfContents a {
248       text-decoration: none;
249       color: black;
250     }
251   }
252
253   @page {
254     @top {
255       content: flow(header);
256     }
257     @bottom {
258       content: flow(footer);
259     }
260     @footnotes {
261       border-top: solid black thin;
262       padding-top: 8pt;
263     }
264   }
265   /* end default print css */
266  
267
268 /* custom css */
269
270
271 /* end custom css */
272
273
274
275   /* ui edited css */
276   
277   body {
278     font-family: Verdana;
279     
280     font-size: 10.0pt;
281     line-height: normal;
282     background-color: #ffffff;
283   }
284   /* end ui edited css */
285
286
287
288 /* editor CSS */
289 .editor a:visited {color: #551A8B}
290 .editor table.zeroBorder {border: 1px dotted gray}
291 .editor table.zeroBorder td {border: 1px dotted gray}
292 .editor table.zeroBorder th {border: 1px dotted gray}
293
294
295 .editor div.google_header, .editor div.google_footer {
296   border: 2px #DDDDDD dashed;
297   position: static;
298   width: 100%;
299   min-height: 2em;
300 }
301
302 .editor .misspell {background-color: yellow}
303
304 .editor .writely-comment {
305   font-size: 9pt; 
306   line-height: 1.4; 
307   padding: 1px; 
308   border: 1px dashed #C0C0C0
309 }
310
311
312 /* end editor CSS */
313 </style>
314
315
316 </head>
317
318 <body onload="DoPageLoad();"
319     
320     revision="dhkdd78p_13kvrgbnfb:231">
321
322     
323     
324     
325 <DIV>\r
326   <DIV>\r
327     <B>Geniwrapper Design Document</B>\r
328   </DIV>\r
329 </DIV>\r
330 <DIV>\r
331   &nbsp;\r
332 </DIV>\r
333 <DIV>\r
334   <B>1.0 High Level Overview</B>\r
335 </DIV>\r
336 <DIV>\r
337   &nbsp;\r
338 </DIV>\r
339 <DIV>\r
340   The purpose of Geniwrapper is to provide a Geni-like interface around the\r
341   existing planetlab infrastructure. The existing infrastructure consists of two\r
342   parts: planetlab central (PLC) and planetlab nodes. These two parts map\r
343   logically into the Geni Registry and Geni Components. However, it is not an\r
344   exact mapping. Due to the nature of planetlab, some component functionality\r
345   overlaps with PLC. For example, PLC takes an active role in managing state on\r
346   planetlab nodes, and therefore some Geni component state exists on PLC,\r
347   leading to some component APIs to exist on PLC.\r
348 </DIV>\r
349 <DIV>\r
350   &nbsp;\r
351 </DIV>\r
352 <DIV>\r
353   Geniwrapper is comprised of the following logical modules: <I>utility\r
354   classes</I>, <I>registry wrapper</I>, <I>component wrapper</I>, and <I>command\r
355   line client</I>. Client-server communication uses a variant of XML-RPC called\r
356   the <I>Geni protocol</I>. Section 1 of this document presents a very brief\r
357   overview of each module. In-depth discussion occurs later.\r
358 </DIV>\r
359 <DIV>\r
360   &nbsp;\r
361 </DIV>\r
362 <DIV>\r
363   Much of this design adheres to the SFA, and as such this document avoids\r
364   duplication of the information already presented in the SFA. For example, the\r
365   description of privileges, which operations are allowed by a specific\r
366   privileges, and how privileges are assigned to principals is described fully\r
367   in the SFA and is therefore not duplicated here.\r
368 </DIV>\r
369 <DIV>\r
370   &nbsp;\r
371 </DIV>\r
372 <DIV>\r
373   NOTE: <b>API documentation</b> is extracted from code comments automatically\r
374   and is maintained in separate files, one documentation file corresponding to\r
375   each python source file. An effort has been made to keep API documentation\r
376   separate from this document, so that the API documentation may be\r
377   self-maintaining as the code is updated.\r
378 </DIV>\r
379 <DIV>\r
380   &nbsp;\r
381 </DIV>\r
382 <DIV>\r
383   Geniwrapper is checked into a subversion repository at\r
384   <A href=http://svn.planetlab.org/geniwrapper>http://svn.planetlab.org/geniwrapper</A>.\r
385   [TODO: verify link]\r
386 </DIV>\r
387 <DIV>\r
388   &nbsp;\r
389 </DIV>\r
390 <DIV>\r
391   <DIV>\r
392     <B>1.1 Utility classes</B>\r
393   </DIV>\r
394   <DIV>\r
395     &nbsp;\r
396   </DIV>\r
397   <DIV>\r
398     Utility classes include python classes that implement certificates, GIDs,\r
399     credentials, and tickets. There are also utility classes for implementing\r
400     the server and client stubs and the security protocol. The utility modules\r
401     are designed to be generally re-usable. For example, the credential\r
402     management class may be used as part of the Geni Registry, Geni Components,\r
403     and the end-user tools that interact with Geni.\r
404   </DIV>\r
405   <DIV>\r
406     &nbsp;\r
407   </DIV>\r
408   <DIV>\r
409     The&nbsp;utility classes&nbsp;are located in the\r
410     <I>util</I>&nbsp;subdirectory.\r
411   </DIV>\r
412 </DIV>\r
413 <DIV>\r
414   &nbsp;\r
415 </DIV>\r
416 <DIV>\r
417   <B>1.2 The registry (PLC) wrapper</B>\r
418 </DIV>\r
419 <DIV>\r
420   &nbsp;\r
421 </DIV>\r
422 <DIV>\r
423   The registry wrapper is intended to be colocated with PLC. All communication\r
424   between the registry wrapper and PLC uses the PLCAPI interface and as such,\r
425   the registry wrapper can be run on a separate machine for ease of development.\r
426   In addition to the Geni registry operations (register, update, ...), the\r
427   registry also implements component operations, such as GetTicket, that must be\r
428   located on PLC due to SFA engineering decisions.\r
429 </DIV>\r
430 <DIV>\r
431   &nbsp;\r
432 </DIV>\r
433 <DIV>\r
434   The&nbsp;registry wrapper is located in the&nbsp;<I>registry</I> subdirectory\r
435 </DIV>\r
436 <DIV>\r
437   &nbsp;\r
438 </DIV>\r
439 <DIV>\r
440   TODO: Slice interface shall be implemented in registry wrapper.\r
441 </DIV>\r
442 <DIV>\r
443   &nbsp;\r
444 </DIV>\r
445 <DIV>\r
446   <B>1.3&nbsp;The component wrapper</B>\r
447 </DIV>\r
448 <DIV>\r
449   &nbsp;\r
450 </DIV>\r
451 <DIV>\r
452   The component wrapper is located on planetlab nodes. It implements the\r
453   component interface, management interface, and portions of the slice\r
454   interface. Due to SFA engineering decisions, some component operations (i.e.\r
455   GetTicket) are implemented in the registry wrapper instead of the component\r
456   wrapper.\r
457 </DIV>\r
458 <DIV>\r
459   &nbsp;\r
460 </DIV>\r
461 <DIV>\r
462   The component wrapper is located in the <I>component</I> subdirectory.\r
463 </DIV>\r
464 <DIV>\r
465   &nbsp;\r
466 </DIV>\r
467 <DIV>\r
468   <B>1.4 Command line client</B>\r
469 </DIV>\r
470 <DIV>\r
471   &nbsp;\r
472 </DIV>\r
473 <DIV>\r
474   The command line client exports a client interface to Geni that may be used\r
475   for testing and demonstration purposes. It allows easy invocation of Geni api\r
476   functions and dumps the results in a human-readable format.\r
477 </DIV>\r
478 <DIV>\r
479   &nbsp;\r
480 </DIV>\r
481 <DIV>\r
482   The command line client&nbsp;is located in the&nbsp;<I>cmdline</I>\r
483   subdirectory\r
484 </DIV>\r
485 <DIV>\r
486   &nbsp;\r
487 </DIV>\r
488 <DIV>\r
489   <B>1.5 Geni Protocol</B>\r
490 </DIV>\r
491 <DIV>\r
492   &nbsp;\r
493 </DIV>\r
494 <DIV>\r
495   The Geni protocol is based on XML-RPC. It is implemented primarily in the\r
496   geniserver.py and geniclient.py files located with the utility classes.\r
497   Modifications to the XML-RPC protocol include the following:\r
498 </DIV>\r
499 <DIV>\r
500   &nbsp;\r
501 </DIV>\r
502 <OL>\r
503   <LI>\r
504     The transport mechanism uses HTTPS instead of HTTP.\r
505     <LI>\r
506       HTTPS certificate verification is disabled so that custom Geni\r
507       verification based on GID can be done instead.\r
508       <LI>\r
509         When an exception occurs on the server, verbose exception information is\r
510         sent to the client, to assist debugging efforts\r
511       </LI>\r
512 </OL>\r
513 <DIV>\r
514   &nbsp;\r
515 </DIV>\r
516 <DIV>\r
517   Authentication:\r
518 </DIV>\r
519 <DIV>\r
520   &nbsp;\r
521 </DIV>\r
522 <DIV>\r
523   Authentication of the client by the server is done by using Credentials/GIDs.\r
524   Generally, each operation contains a credential as the first argument. This\r
525   credential includes the GID of the caller, which in turn contains the public\r
526   key of the caller. The server ensures that this public key matches the public\r
527   key that is being used to decrypt the HTTPS connection, thus ensuring the\r
528   caller must posess the private key that corresponds to the GID.\r
529 </DIV>\r
530 <DIV>\r
531   &nbsp;\r
532 </DIV>\r
533 <DIV>\r
534   Authentication of the server by the client is left as an exercise for the\r
535   client. It may be done easily by specifying the server's public key when the\r
536   client create the HTTPS connection. This presumes the client knows the public\r
537   key (or GID) of the server he is trying to connect to.\r
538 </DIV>\r
539 <DIV>\r
540   &nbsp;\r
541 </DIV>\r
542 <DIV>\r
543   <B>2.0 Utility Classes</B>\r
544 </DIV>\r
545 <DIV>\r
546   &nbsp;\r
547 </DIV>\r
548 <DIV>\r
549   <B>2.1 Certificates and Keys (cert.py)</B>\r
550 </DIV>\r
551 <DIV>\r
552   &nbsp;\r
553 </DIV>\r
554 <DIV>\r
555   Geniwrapper uses two crypto libraries: pyOpenSSL and M2Crypto to implement the\r
556   necessary crypto functionality. Ideally just one of these libraries would be\r
557   used, but unfortunately each of these libraries is independently lacking. The\r
558   pyOpenSSL library is missing many necessary functions, and the M2Crypto\r
559   library has crashed inside of some of the functions. The design decision is to\r
560   use pyOpenSSL whenever possible as it seems more stable, and only use M2Crypto\r
561   for those functions that are not possible in pyOpenSSL.\r
562 </DIV>\r
563 <DIV>\r
564   &nbsp;\r
565 </DIV>\r
566 <DIV>\r
567   <B>2.1.1 Keys</B>\r
568 </DIV>\r
569 <DIV>\r
570   &nbsp;\r
571 </DIV>\r
572 <DIV>\r
573   Public-private key pairs are implemented by the <B>Keypair </B>class. A\r
574   Keypair object may represent both a public and private key pair, or it may\r
575   represent only a public key (this usage is consistent with OpenSSL).\r
576 </DIV>\r
577 <P>\r
578   &nbsp;&nbsp;&nbsp;&nbsp;\r
579 </P>\r
580 <DIV>\r
581   <B>2.1.2 Certificates</B>\r
582 </DIV>\r
583 <DIV>\r
584   &nbsp;\r
585 </DIV>\r
586 <DIV>\r
587   The certificate class implements a general purpose X509 certificate, making\r
588   use of the appropriate pyOpenSSL or M2Crypto abstractions. It also adds\r
589   several addition features, such as the ability to maintain a chain of parent\r
590   certificates, and storage of application-specific data.\r
591 </DIV>\r
592 <DIV>\r
593   &nbsp;\r
594 </DIV>\r
595 <DIV>\r
596   Certificates include the ability to maintain a chain of parents. Each\r
597   certificate includes a pointer to it's parent certificate. When loaded from a\r
598   file or a string, the parent chain will be automatically loaded. When saving a\r
599   certificate to a file or a string, the caller can choose whether to save the\r
600   parent certificates as well.\r
601 </DIV>\r
602 <DIV>\r
603   &nbsp;\r
604 </DIV>\r
605 <DIV>\r
606   Example creation of a certificate:\r
607 </DIV>\r
608 <DIV>\r
609   &nbsp;\r
610 </DIV>\r
611 <DIV>\r
612   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # create&nbsp;a key for an issuer<BR>\r
613   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; issuerKey = Keypair(create=True)<BR>\r
614   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; issuerSubject = "testissuer"\r
615 </DIV>\r
616 <DIV>\r
617   &nbsp;\r
618 </DIV>\r
619 <DIV>\r
620   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # create a key for the certificate\r
621 </DIV>\r
622 <DIV>\r
623   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; userKey = KeyPair(create=True)\r
624 </DIV>\r
625 <DIV>\r
626   &nbsp;\r
627 </DIV>\r
628 <DIV>\r
629   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # create the certificate, set the issuer, and\r
630   sign it\r
631 </DIV>\r
632 <DIV>\r
633   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cert = Certificate(subject="test")<BR>\r
634   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cert.set_issuer(issuerKey, issuerSubject)\r
635 </DIV>\r
636 <DIV>\r
637   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cert.set_pubkey(userKey)<BR>\r
638   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cert.sign()\r
639 </DIV>\r
640 <DIV>\r
641   &nbsp;\r
642 </DIV>\r
643 <DIV>\r
644   <B>2.1.3 Certificate Verification</B>\r
645 </DIV>\r
646 <DIV>\r
647   &nbsp;\r
648 </DIV>\r
649 <DIV>\r
650   <P>\r
651     Verification examines a chain of certificates to ensure that each parent\r
652     signs the child, and that some certificate in the chain is signed by a\r
653     trusted certificate. Verification is a basic recursion:\r
654   </P>\r
655   <PRE>    if this_certificate was signed by trusted_certs:<BR>        return<BR>    else<BR>        return verify_chain(parent, trusted_certs)</PRE>\r
656 </DIV>\r
657 <DIV>\r
658   At each recursion, the parent is tested to ensure that it did sign the child.\r
659   If a parent did not sign a child, then an exception is thrown. If the bottom\r
660   of the recursion is reached and the certificate does not match a trusted root,\r
661   then an exception is thrown.\r
662 </DIV>\r
663 <DIV>\r
664   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>\r
665   <B>2.2 GIDS (gid.py)</B>\r
666 </DIV>\r
667 <DIV>\r
668   <B></B>&nbsp;\r
669 </DIV>\r
670 <DIV>\r
671   GIDs are a derivative class of certificates and as such the&nbsp;GID class\r
672   inherits all the methods of the certificate class. A&nbsp;GID includes a tuple\r
673   of the following fields:&nbsp;\r
674 </DIV>\r
675 <DIV>\r
676   &nbsp;\r
677 </DIV>\r
678 <DIV>\r
679   &nbsp;&nbsp; (uuid, hrn, public_key)\r
680 </DIV>\r
681 <DIV>\r
682   &nbsp;\r
683 </DIV>\r
684 <DIV>\r
685   UUID is a unique identifier and is created by the python uuid module (or the\r
686   utility function create_uuid() in gid.py).\r
687 </DIV>\r
688 <DIV>\r
689   &nbsp;\r
690 </DIV>\r
691 <DIV>\r
692   HRN is a human readable name. It is a dotted form similar to a backward domain\r
693   name. For example, planetlab.us.arizona.bakers.\r
694 </DIV>\r
695 <DIV>\r
696   &nbsp;\r
697 </DIV>\r
698 <DIV>\r
699   PUBLIC_KEY is the public key of the principal identified by the UUID/HRN. It\r
700   is a Keypair object as defined in the cert.py module.\r
701 </DIV>\r
702 <DIV>\r
703   &nbsp;\r
704 </DIV>\r
705 <DIV>\r
706   It is expected that there is a one-to-one pairing between UUIDs and HRN, but\r
707   it is uncertain how this would be inforced or if it needs to be enforced.\r
708 </DIV>\r
709 <DIV>\r
710   &nbsp;\r
711 </DIV>\r
712 <DIV>\r
713   <B>2.2.1 Encoding and Decoding</B>\r
714 </DIV>\r
715 <DIV>\r
716   &nbsp;\r
717 </DIV>\r
718 <DIV>\r
719   The 5 fields of the&nbsp;GID tuple are stored in the subject-alt-name field of\r
720   the X509 certificate. Two routines are included to package and unpackage these\r
721   fields: Encode() and Decode(). Encode should be called prior to signing the\r
722   GID. Decode is automatically called on demand by the various get_*()\r
723   functions.\r
724 </DIV>\r
725 <DIV>\r
726   &nbsp;\r
727 </DIV>\r
728 <DIV>\r
729   <B>2.2.2 Verification of GIDs</B>\r
730 </DIV>\r
731 <DIV>\r
732   &nbsp;\r
733 </DIV>\r
734 Verification first performs the checks of the certificate class (verifying that\r
735 each parent signs the child, etc). In addition, GIDs also confirm that the\r
736 parent's HRN is a prefix of the child's HRN. Verifying these prefixes prevents a\r
737 rogue authority from signing a GID for a principal that is not a member of that\r
738 authority. For example, planetlab.us.arizona cannot sign a GID for\r
739 planetlab.us.princeton.foo.\r
740 <DIV>\r
741   &nbsp;\r
742 </DIV>\r
743 <DIV>\r
744   <B>2.3 Credentials (credential.py)</B>\r
745 </DIV>\r
746 <DIV>\r
747   &nbsp;\r
748 </DIV>\r
749 <DIV>\r
750   Credentials are a derivative class of certificates and as such the credential\r
751   class inherits all the methods of the certificate class. A credential includes\r
752   a tuple of the following fields:\r
753 </DIV>\r
754 <DIV>\r
755   &nbsp;\r
756 </DIV>\r
757 <DIV>\r
758   &nbsp;&nbsp;&nbsp; (GIDCaller, GIDObject, LifeTime, Privileges, Delegate)\r
759 </DIV>\r
760 <DIV>\r
761   &nbsp;\r
762 </DIV>\r
763 <DIV>\r
764   GIDCaller identifies the holder of the credential. When a credential is\r
765   presented to a component, the security layer ensures that the client matches\r
766   the public key that is contained in GIDCaller.\r
767 </DIV>\r
768 <DIV>\r
769   &nbsp;\r
770 </DIV>\r
771 <DIV>\r
772   GIDObject identifies the object of the credential. This object depends upon\r
773   the type of the credential. For example, the credential for a user likely has\r
774   GIDObject == GIDCaller. Credentials for slices would include the GID of the\r
775   slice in the GIDObject field. Credentials for authorities include the GID of\r
776   the authority in the GIDObject field.\r
777 </DIV>\r
778 <DIV>\r
779   &nbsp;\r
780 </DIV>\r
781 <DIV>\r
782   LifeTime is the lifetime of the credential. Currently not implemented; expect\r
783   to implement it as an expiration date, and refuse credentials beyond that\r
784   date.\r
785 </DIV>\r
786 <DIV>\r
787   &nbsp;\r
788 </DIV>\r
789 <DIV>\r
790   Privileges is a Rights object that describes the rights that are granted to\r
791   the holder of the credential.\r
792 </DIV>\r
793 <DIV>\r
794   &nbsp;\r
795 </DIV>\r
796 <DIV>\r
797   Delegate is a True/False bit that indicates whether or not a credential can be\r
798   delegated to a different caller.\r
799 </DIV>\r
800 <DIV>\r
801   &nbsp;\r
802 </DIV>\r
803 <DIV>\r
804   <B>2.3.1 Encoding and Decoding</B>\r
805 </DIV>\r
806 <DIV>\r
807   &nbsp;\r
808 </DIV>\r
809 <DIV>\r
810   The 5 fields of the credential tuple are stored in the subject-alt-name field\r
811   of the X509 certificate. Two routines are included to package and unpackage\r
812   these fields: Encode() and Decode(). Encode should be called prior to signing\r
813   the credential. Decode is automatically called on demand by the various\r
814   get_*() functions.\r
815 </DIV>\r
816 <DIV>\r
817   &nbsp;\r
818 </DIV>\r
819 <DIV>\r
820   <B>2.3.2 Verification of Credentials</B>\r
821 </DIV>\r
822 <DIV>\r
823   &nbsp;\r
824 </DIV>\r
825 <DIV>\r
826   In addition to the checks for ordinary certificates, verification of\r
827   credentials also ensures that the delegate bit was set by each parent in the\r
828   chain. If a delegate bit was not set, then an exception is thrown.&nbsp;Each\r
829   credential must also contain a subset of the rights of the parent credential\r
830   (i.e. a user credential cannot delegate authority rights).<BR>\r
831   <BR>\r
832   <B>2.4 Rights (rights.py)<BR>\r
833   <BR>\r
834   </B>Rights are implemented by two classes:<BR>\r
835   <BR>\r
836   Right - represents a single right<BR>\r
837   RightList - represents a list of rights A right may allow several different\r
838   operations.<BR>\r
839   <BR>\r
840   For example, the "info" right allows "listslices", "listcomponentresources",\r
841   etc.<BR>\r
842   <BR>\r
843   <B>2.5 Records (record.py)</B><BR>\r
844 </DIV>\r
845 <DIV>\r
846   &nbsp;\r
847 </DIV>\r
848 <DIV>\r
849   The GeniRecord class implements a Geni Record. The GeniRecord class implements\r
850   an abstract interface for the record, so that a client may use records without\r
851   having to understant the underlying implementation details, such as whether\r
852   the record is realized in the registry database, a local cache, or has been\r
853   transmitted over the wire by an interface. A GeniRecord is a tuple (Name, GID,\r
854   Type, Info).\r
855 </DIV>\r
856 <DIV>\r
857   &nbsp;\r
858 </DIV>\r
859 <DIV>\r
860   &nbsp; Name specifies the HRN of the object GID is the GID of the object\r
861 </DIV>\r
862 <DIV>\r
863   &nbsp;\r
864 </DIV>\r
865 <DIV>\r
866   &nbsp; Type is user | sa | ma | slice | component Info is comprised of the\r
867   following sub-fields\r
868 </DIV>\r
869 <DIV>\r
870   &nbsp;\r
871 </DIV>\r
872 <DIV>\r
873   &nbsp; Pointer&nbsp;is a pointer to the record in the PL database\r
874 </DIV>\r
875 <DIV>\r
876   &nbsp;\r
877 </DIV>\r
878 <DIV>\r
879   &nbsp; pl_info&nbsp;is planetlab-specific info (when talking to client)\r
880 </DIV>\r
881 <DIV>\r
882   &nbsp;\r
883 </DIV>\r
884 <DIV>\r
885   &nbsp; geni_info = geni-specific info (when talking to client)\r
886 </DIV>\r
887 <DIV>\r
888   &nbsp;\r
889 </DIV>\r
890 <DIV>\r
891   The pointer is interpreted depending on the type of the record. For example,\r
892   if the type=="user", then pointer is assumed to be a person_id that indexes\r
893   into the persons table.\r
894 </DIV>\r
895 <DIV>\r
896   &nbsp;\r
897 </DIV>\r
898 <DIV>\r
899   A given HRN may have more than one record, provided that the records are of\r
900   different types. For example, planetlab.us.arizona may have both an SA and a\r
901   MA record, but cannot have two SA records.\r
902 </DIV>\r
903 <DIV>\r
904   &nbsp;\r
905 </DIV>\r
906 <DIV>\r
907   <B>2.6 Tickets (geniticket.py)</B>\r
908 </DIV>\r
909 <DIV>\r
910   &nbsp;\r
911 </DIV>\r
912 <DIV>\r
913   Similar to GIDs and Credentials, tickets also leverage the certificate object.\r
914 </DIV>\r
915 <DIV>\r
916   &nbsp;\r
917 </DIV>\r
918 <DIV>\r
919   A Ticket is tuple:<BR>\r
920   &nbsp;&nbsp; (gidCaller, gidObject, attributes, rspec, delegate)<BR>\r
921   <BR>\r
922   &nbsp;&nbsp;&nbsp; gidCaller = GID of the caller performing the operation<BR>\r
923   &nbsp;&nbsp;&nbsp; gidObject = GID of the slice<BR>\r
924   &nbsp;&nbsp;&nbsp; attributes = slice attributes (keys, vref, instantiation,\r
925   etc)<BR>\r
926   &nbsp;&nbsp;&nbsp; rspec = resources\r
927 </DIV>\r
928 <DIV>\r
929   &nbsp;\r
930 </DIV>\r
931 <DIV>\r
932   Tickets are created by invoking GetTicket() on the Registry. The slice\r
933   attributes and rspec are taken from the planetlab slice database and represent\r
934   the current state of the slice. As of yet, tickets do not include any concept\r
935   of time -- a ticket represents the state of the slice at the current time\r
936   only.\r
937 </DIV>\r
938 <DIV>\r
939   &nbsp;\r
940 </DIV>\r
941 <DIV>\r
942   Tickets are redeemed by invoking RedeemTicket() on the Registry. The\r
943   attributes and spec are combined back into a planetlab slice record and handed\r
944   off to the node manager.\r
945 </DIV>\r
946 <DIV>\r
947   &nbsp;\r
948 </DIV>\r
949 <DIV>\r
950   Tickets are signed by an authority and include parentage information that\r
951   traces the chain of authorities back to a trusted root.\r
952 </DIV>\r
953 <DIV>\r
954   &nbsp;\r
955 </DIV>\r
956 <DIV>\r
957   <B>2.6.1 rspecs</B>\r
958 </DIV>\r
959 <DIV>\r
960   &nbsp;\r
961 </DIV>\r
962 <DIV>\r
963   The rspec is currently a dictionary of {name: value} pairs. These pairs are\r
964   taken verbatim from the planetlab slice database.\r
965 </DIV>\r
966 <DIV>\r
967   &nbsp;\r
968 </DIV>\r
969 <DIV>\r
970   The general rule that is used is that things in the slice record that do not\r
971   specifically imply a tangible resource (initscripts, keys, etc) are treated as\r
972   attributes and things that do specify a tangible resource (disk, network, etc)\r
973   are treated as the rspec.\r
974 </DIV>\r
975 <DIV>\r
976   &nbsp;\r
977 </DIV>\r
978 <DIV>\r
979   TODO: The definition of an rspec is evolving. It remains to reconcile the\r
980   eclipse schema with Geniwrapper. Gacks is also using another rspec format,\r
981   which may be need to be reconciled with the eclipse schema and/or geniwrapper.\r
982 </DIV>\r
983 <DIV>\r
984   &nbsp;\r
985 </DIV>\r
986 <DIV>\r
987   <DIV>\r
988     <B>2.6.2 Encoding and Decoding</B>\r
989   </DIV>\r
990   <DIV>\r
991     &nbsp;\r
992   </DIV>\r
993   <DIV>\r
994     The 5 fields of the credential tuple are stored in the subject-alt-name\r
995     field of the X509 certificate. Two routines are included to package and\r
996     unpackage these fields: Encode() and Decode(). Encode should be called prior\r
997     to signing the ticket. Decode is automatically called on demand by the\r
998     various get_*() functions.\r
999   </DIV>\r
1000   <DIV>\r
1001     &nbsp;\r
1002   </DIV>\r
1003   <DIV>\r
1004     <B>2.6.3 Verification of Tickets</B>\r
1005   </DIV>\r
1006   <DIV>\r
1007     &nbsp;\r
1008   </DIV>\r
1009   <DIV>\r
1010     Verification uses the standard parentage verification provided by the\r
1011     certificate class. Specifically, each certificate is signed by a parent, and\r
1012     some certificate must resolve to the trusted root set that is specified on\r
1013     the component.\r
1014   </DIV>\r
1015   <DIV>\r
1016     &nbsp;\r
1017   </DIV>\r
1018   <DIV>\r
1019     Unlike credentials and GIDs, the parent of a ticket may be a degenerate\r
1020     ticket that does not include the full 5-tuple (caller, object, attributes,\r
1021     rspec, delegate). In such a case, the parent is just a placeholder in the\r
1022     chain of authority used to convey the parentage information.\r
1023   </DIV>\r
1024   <DIV>\r
1025     &nbsp;\r
1026   </DIV>\r
1027   <DIV>\r
1028     Delegation of tickets is not something that is discussed in the SFA, but it\r
1029     is supported in the ticket class and may be a useful feature. For example,\r
1030     Alice may hold a ticket for a particular component, and delegate that ticket\r
1031     to Bob. Bob could then instantiate a slice for Alice. This may be one way to\r
1032     implement a slice manager.<BR>\r
1033     <BR>\r
1034     <B>2.7 Hierarchy of Authorities (hierarchy.py)</B><BR>\r
1035     <BR>\r
1036     This module implements a hierarchy of authorities and performs a similar\r
1037     function as the "tree" module of the original geniwrapper prototype. An HRN\r
1038     is assumed to be a string of authorities separated by dots. For example,\r
1039     "planetlab.us.arizona.bakers". Each component of the HRN is a different\r
1040     authority, with the last component being a leaf in the tree. Each authority\r
1041     is stored in a subdirectory on the registry.<BR>\r
1042     <BR>\r
1043     Inside this subdirectory are several files:<BR>\r
1044     *.GID - GID file<BR>\r
1045     *.PKEY - private key file<BR>\r
1046     *.DBINFO - database info<BR>\r
1047     <BR>\r
1048     The hierarchy class can be used to create GIDs, Credentials, and Tickets for\r
1049     a given authority.\r
1050   </DIV>\r
1051 </DIV>\r
1052 <DIV>\r
1053   &nbsp;\r
1054 </DIV>\r
1055 <DIV>\r
1056   The default behavior is that all authorities contained in the hierarchy will\r
1057   be located together in a single physical registry. However, this is not\r
1058   strictly necessary. The *.DBINFO files contain the database information for an\r
1059   authority and can easily be configured to point to other machines. How an\r
1060   authority would cause the DBINFO files to be installed in the correct places\r
1061   is left as a separate exercise, possibly via an out-of-band management\r
1062   interface or a web page.\r
1063 </DIV>\r
1064 <DIV>\r
1065   <BR>\r
1066   <B>2.8 Configuration Information (config.py)</B><BR>\r
1067   <BR>\r
1068   This module holds configuration parameters for geniwrapper. There are two main\r
1069   pieces of information that are used: the database connection and the PLCAPI\r
1070   connection.<BR>\r
1071   <BR>\r
1072   Geniwrapper uses a MYSQL database to store records. This database may be\r
1073   co-located with the PLC database, or it may be a separate database. The\r
1074   following parameters define the connection to the database. Note that\r
1075   Geniwrapper does not access any of the PLC databases directly via a mysql\r
1076   connection; All PLC databases are accessed via PLCAPI.<BR>\r
1077 </DIV>\r
1078 <P>\r
1079   Geniwrapper uses a PLCAPI connection to perform operations on the registry,\r
1080   such as creating and deleting slices. This connection requires an account on\r
1081   the PLC server with full administrator access. The Url parameter controls\r
1082   whether the connection uses PLCAPI directly (i.e. Geniwrapper is located on\r
1083   the same machine as PLC), or uses a XMLRPC connection to the PLC machine. If\r
1084   you wish to use the API directly, then remove the Url field from the\r
1085   dictionary.\r
1086 </P>\r
1087 <DIV>\r
1088   <BR>\r
1089   <B>2.8.1 Database Configuration</B>\r
1090 </DIV>\r
1091 <DIV>\r
1092   &nbsp;\r
1093 </DIV>\r
1094 <DIV>\r
1095   Below is an example database configuration from config.py:\r
1096 </DIV>\r
1097 <DIV>\r
1098   &nbsp;\r
1099 </DIV>\r
1100 <DIV>\r
1101   def get_default_dbinfo():<BR>\r
1102   &nbsp;&nbsp;&nbsp; dbinfo={}<BR>\r
1103   &nbsp;&nbsp;&nbsp; dbinfo['dbname'] = 'planetlab4'<BR>\r
1104   &nbsp;&nbsp;&nbsp; dbinfo['address'] = 'localhost'<BR>\r
1105   &nbsp;&nbsp;&nbsp; dbinfo['port'] = 5432<BR>\r
1106   &nbsp;&nbsp;&nbsp; dbinfo['user'] = 'pgsqluser'<BR>\r
1107   &nbsp;&nbsp;&nbsp; dbinfo['password'] = '4c77b272-c892-4bdf-a833-dddeeee1a2ed'\r
1108 </DIV>\r
1109 <DIV>\r
1110   &nbsp;&nbsp;&nbsp; return dbinfo\r
1111 </DIV>\r
1112 <DIV>\r
1113   &nbsp;\r
1114 </DIV>\r
1115 <DIV>\r
1116   This identifies several important pieces of the database configuration. The\r
1117   name specifies the database name as used by pgsql. The address is the hostname\r
1118   (or ip-address) of the machine that is hosting the database. It is most likely\r
1119   the local machine. Port specifies the socket port where the pgsql is\r
1120   listening. The user and password authenticate Geniwrapper to the pgsql\r
1121   database. In this example, an existing PLC database was used. This is not\r
1122   strictly necessary as only Geni-specific information is stored in this\r
1123   database. A separate database could be used, on a separate machine than PLC if\r
1124   desired.\r
1125 </DIV>\r
1126 <DIV>\r
1127   &nbsp;\r
1128 </DIV>\r
1129 <DIV>\r
1130   <B>2.8.2 PLCAPI Configuration</B>\r
1131 </DIV>\r
1132 <DIV>\r
1133   &nbsp;\r
1134 </DIV>\r
1135 <DIV>\r
1136   Blow is an example PLCAPI configuration from config.py:\r
1137 </DIV>\r
1138 <DIV>\r
1139   &nbsp;\r
1140 </DIV>\r
1141 <DIV>\r
1142   def get_pl_auth():<BR>\r
1143   &nbsp;&nbsp;&nbsp; pl_auth = {'Username':\r
1144   <A href="mailto:'root@198.0.0.132'">'root@198.0.0.132'</A>,<BR>\r
1145   &nbsp;&nbsp;&nbsp; 'AuthMethod': 'password',<BR>\r
1146   &nbsp;&nbsp;&nbsp; 'AuthString':&nbsp; 'root',<BR>\r
1147   &nbsp;&nbsp;&nbsp; "Url":\r
1148   "<A href=https://localhost/PLCAPI/>https://localhost:443/PLCAPI/</A>"<BR>\r
1149   &nbsp;&nbsp;&nbsp; }\r
1150 </DIV>\r
1151 <DIV>\r
1152   &nbsp;&nbsp;&nbsp; return pl_auth\r
1153 </DIV>\r
1154 <DIV>\r
1155   &nbsp;\r
1156 </DIV>\r
1157 <DIV>\r
1158   The PLCAPI configuration tells Geniwrapper how to connect to PLC. There are\r
1159   two options: a local connection or a remote connection. If the Url field is\r
1160   defined, then a remote connection is assumed, and Geniwrapper will attempt to\r
1161   connect via XMLRPC to a remote PLCAPI server. If the Url field is not defined,\r
1162   then Geniwrapper will assume that PYTHONPATH includes the relevant PLCAPI\r
1163   classes to use PLCAPI directly.\r
1164 </DIV>\r
1165 <DIV>\r
1166   &nbsp;\r
1167 </DIV>\r
1168 <DIV>\r
1169   Username specifies the name of the PLCAPI user. It is suggested that a user\r
1170   with full administrative authority be allowed. Otherwise, Geniwrapper will be\r
1171   unable to lookup public keys and other information that PLC does not make\r
1172   available publicly. Administrative permission is also required to create PLC\r
1173   sites, users, etc. Authmethod and AuthString specify the password require to\r
1174   use this account.\r
1175 </DIV>\r
1176 <DIV>\r
1177   &nbsp;\r
1178 </DIV>\r
1179 <DIV>\r
1180   <B>3.0 The Registry Wrapper</B>\r
1181 </DIV>\r
1182 <DIV>\r
1183   &nbsp;\r
1184 </DIV>\r
1185 <DIV>\r
1186   This wrapper implements the Geni Registry. According to the SFA, the basic\r
1187   functionality of a registry is to map HRNs into records. However, because of\r
1188   the interactions between Geniwrapper and PLC, the registry does more than act\r
1189   as a simple database. The registry performs API calls on PLC that create\r
1190   slices, sites, users, etc., and as such may indirectly cause slices to be\r
1191   instantiated on components, because components are also linked to PLC.\r
1192 </DIV>\r
1193 <DIV>\r
1194   &nbsp;\r
1195 </DIV>\r
1196 <DIV>\r
1197   The mapping of Geni objects to planetlab objects is relatively\r
1198   straightforward:\r
1199 </DIV>\r
1200 <DIV>\r
1201   &nbsp;\r
1202 </DIV>\r
1203 <DIV>\r
1204   &nbsp;&nbsp;&nbsp; slice&nbsp;= slice\r
1205 </DIV>\r
1206 <DIV>\r
1207   &nbsp;&nbsp;&nbsp; user&nbsp;= person\r
1208 </DIV>\r
1209 <DIV>\r
1210   &nbsp;&nbsp;&nbsp;&nbsp;component = node\r
1211 </DIV>\r
1212 <DIV>\r
1213   &nbsp;&nbsp;&nbsp; sa = site\r
1214 </DIV>\r
1215 <DIV>\r
1216   &nbsp;&nbsp;&nbsp; ma = site\r
1217 </DIV>\r
1218 <DIV>\r
1219   &nbsp;\r
1220 </DIV>\r
1221 <DIV>\r
1222   The one part that is slightly counterintuitive is SA and MA, which both map to\r
1223   the planetlab site object. In a unified registry (a registry that serves as\r
1224   both slice and component registry), these will map to the same site record in\r
1225   the PLC database. However, there are two distinct Geni records, one&nbsp;for\r
1226   the SA and one for the MA.&nbsp;\r
1227 </DIV>\r
1228 <DIV>\r
1229   &nbsp;\r
1230 </DIV>\r
1231 <DIV>\r
1232   Registry operations generally authenticate the&nbsp;caller by credential.\r
1233   There are a few exceptions, and the registry API&nbsp;documents should note\r
1234   those exceptions.&nbsp;\r
1235 </DIV>\r
1236 <DIV>\r
1237   &nbsp;\r
1238 </DIV>\r
1239 <DIV>\r
1240   <B>3.1 Registry Tools</B>\r
1241 </DIV>\r
1242 <DIV>\r
1243   &nbsp;\r
1244 </DIV>\r
1245 <DIV>\r
1246   The registry include several additional tools that are used to manage it.\r
1247   These include:\r
1248 </DIV>\r
1249 <DIV>\r
1250   &nbsp;\r
1251 </DIV>\r
1252 <DIV>\r
1253   import.py - imports existing PLC records into the registry\r
1254 </DIV>\r
1255 <DIV>\r
1256   &nbsp;\r
1257 </DIV>\r
1258 <DIV>\r
1259   nuke.py - deletes all Geni records\r
1260 </DIV>\r
1261 <DIV>\r
1262   &nbsp;\r
1263 </DIV>\r
1264 <DIV>\r
1265   <B>3.1 Bootstrapping a Registry</B>\r
1266 </DIV>\r
1267 <DIV>\r
1268   &nbsp;\r
1269 </DIV>\r
1270 <DIV>\r
1271   There are several items that need to be done before starting the registry.\r
1272 </DIV>\r
1273 <DIV>\r
1274   &nbsp;\r
1275 </DIV>\r
1276 <DIV>\r
1277   1) Update util/config.py to match the parameters of your PLC installation.\r
1278 </DIV>\r
1279 <DIV>\r
1280   &nbsp;\r
1281 </DIV>\r
1282 <DIV>\r
1283   2) Import the existing planetlab database, creating the appropriate geni\r
1284   records. This is done by running the "import.py" tool.\r
1285 </DIV>\r
1286 <DIV>\r
1287   &nbsp;\r
1288 </DIV>\r
1289 <DIV>\r
1290   3) Create a "trusted_roots" directory and place the certificate of the root\r
1291   authority in that directory. Given the defaults in import.py, this certificate\r
1292   would be named "planetlab.gid". For example, mkdir trusted_roots; cp\r
1293   authorities/planetlab.gid trusted_roots/\r
1294 </DIV>\r
1295 <DIV>\r
1296   &nbsp;\r
1297 </DIV>\r
1298 <DIV>\r
1299   <B>4.0 The Component Wrapper</B>\r
1300 </DIV>\r
1301 <DIV>\r
1302   <BR>\r
1303   The Geni Component Wrapper implements the Geni Component Manager. It includes\r
1304   functions for redeeming tickets, starting/stopping/resetting/deleting slices,\r
1305   and management such as rebooting the component.\r
1306 </DIV>\r
1307 <DIV>\r
1308   &nbsp;\r
1309 </DIV>\r
1310 <DIV>\r
1311   The design of the component differs from the registry wrapper in the respect\r
1312   that the component wrapper must be located physically on the planetlab node\r
1313   that it is responsible for. The component wrapper interacts directly with\r
1314   portions of the node manager code on the node.\r
1315 </DIV>\r
1316 <DIV>\r
1317   &nbsp;\r
1318 </DIV>\r
1319 <DIV>\r
1320   <B>4.1 Component Authentication of Credentials</B>\r
1321 </DIV>\r
1322 <DIV>\r
1323   &nbsp;\r
1324 </DIV>\r
1325 <DIV>\r
1326   The component authenticates credentials the same way that the registry does.\r
1327   Specifically, there is a directory of trusted_root certificates (or GIDs) on\r
1328   the component. Any credential presented to the component must include in it's\r
1329   parentage some certificate in the set of trusted roots. Otherwise, and\r
1330   exception is thrown.\r
1331 </DIV>\r
1332 <DIV>\r
1333   &nbsp;\r
1334 </DIV>\r
1335 <DIV>\r
1336   <B>4.2 The Ticket interface</B>\r
1337 </DIV>\r
1338 <DIV>\r
1339   &nbsp;\r
1340 </DIV>\r
1341 <DIV>\r
1342   The ticket interface is split between the Registry (PLC) and the Component.\r
1343   This is due to the SFA engineering decisions, specifically&nbsp;that the\r
1344   authoritative copy of planetlab state is stored on PLC and only cached on the\r
1345   components. Thus, GetTicket() is implemented on the Registry, and\r
1346   RedeemTicket() is implemented on the component. InstantiateSlice is not\r
1347   implemented, as that operation is a combination of GetTicket/RedeemTicket and\r
1348   would therefore span the Registry and Component.\r
1349 </DIV>\r
1350 <DIV>\r
1351   &nbsp;\r
1352 </DIV>\r
1353 <DIV>\r
1354   <B>4.3 Sliver Credentials</B>\r
1355 </DIV>\r
1356 <DIV>\r
1357   &nbsp;\r
1358 </DIV>\r
1359 <DIV>\r
1360   A recent Geni Architecture call mentioned the need for sliver credentials. A\r
1361   sliver credential would be identical to a slice credential, but would 1) only\r
1362   be redeemable on a particular component, and 2) would resolve to a\r
1363   trusted_root unique to that component (likely the component's GID\r
1364   certificate). Sliver credentials would be returned by the RedeemTicket call\r
1365   and would give the caller the permission required to start and stop the\r
1366   sliver, etc.\r
1367 </DIV>\r
1368 <DIV>\r
1369   &nbsp;\r
1370 </DIV>\r
1371 <DIV>\r
1372   Sliver credentials are not yet implemented, but their implementation would be\r
1373   straightforward.\r
1374 </DIV>\r
1375 <DIV>\r
1376   &nbsp;\r
1377 </DIV>\r
1378 <DIV>\r
1379   <B>4.4 Bootstrapping the Component Wrapper</B>\r
1380 </DIV>\r
1381 <DIV>\r
1382   &nbsp;\r
1383 </DIV>\r
1384 <DIV>\r
1385   The first step is to install some required libraries on the component. These\r
1386   include the m2crypto and pyopenssl libraries. Installing the actual RPMs for\r
1387   these libaries on a running component proved difficult due to additional\r
1388   support packages that require installation (python-devel, etc). For\r
1389   development purposes, it was sufficient to copy the installed/compiled version\r
1390   of the libraries from the development machine to the component.\r
1391 </DIV>\r
1392 <DIV>\r
1393   &nbsp;\r
1394 </DIV>\r
1395 <DIV>\r
1396   The&nbsp;second step is to copy the files required by the component wrapper to\r
1397   the node manager. They are copied to the /usr/share/Nodemanager directory. A\r
1398   list of the files is contained in the copynode.sh script in the component\r
1399   subdirectory.\r
1400 </DIV>\r
1401 <DIV>\r
1402   &nbsp;\r
1403 </DIV>\r
1404 <DIV>\r
1405   The third step is to copy the trusted root certificates to the component. They\r
1406   are stored in /usr/share/Nodemanager/trusted_roots. This should include the\r
1407   certificate for the registry.\r
1408 </DIV>\r
1409 <DIV>\r
1410   &nbsp;\r
1411 </DIV>\r
1412 <DIV>\r
1413   The&nbsp;fourth step is to start the component manager. This is done by\r
1414   connecting to the component via SSH and running\r
1415   /usr/share/Nodemanager/component.py.\r
1416 </DIV>\r
1417 <DIV>\r
1418   <BR>\r
1419   In a production environment, all of these steps would be integrated into the\r
1420   DVD boot image for the planetlab node.\r
1421 </DIV>\r
1422 <DIV>\r
1423   &nbsp;\r
1424 </DIV>\r
1425 <DIV>\r
1426   <B>5.0 Command-Line Interface</B>\r
1427 </DIV>\r
1428 <DIV>\r
1429   &nbsp;\r
1430 </DIV>\r
1431 <DIV>\r
1432   A command-line interface is provided that allows a user to interact with the\r
1433   Geni Registry and Component. This command line interface is located in the\r
1434   cmdline directory and can be invoked by running genicli.py. Specifying\r
1435   "genicli.py help" will display a list of available commands.\r
1436 </DIV>\r
1437 <DIV>\r
1438   &nbsp;\r
1439 </DIV>\r
1440 <DIV>\r
1441   <B>5.1 Examples</B>\r
1442 </DIV>\r
1443 <DIV>\r
1444   &nbsp;\r
1445 </DIV>\r
1446 <DIV>\r
1447   Several examples of using the CLI are presented in the form of shell scripts\r
1448   in the cmdline directory. These scripts demonstrate creating slices,\r
1449   authorities, users, nodes, and getting tickets and redeeming tickets. Rather\r
1450   than duplicating all of those examples here, a few short examples are\r
1451   presented below.\r
1452 </DIV>\r
1453 <DIV>\r
1454   &nbsp;\r
1455 </DIV>\r
1456 <DIV>\r
1457   <B>5.1.1 Getting a Credential</B>\r
1458 </DIV>\r
1459 <DIV>\r
1460   &nbsp;\r
1461 </DIV>\r
1462 <DIV>\r
1463   python ./genicli.py --username&nbsp;root --credfile None --outfile test.cred\r
1464   getCredential user planetlab.us.pl.account_test\r
1465 </DIV>\r
1466 <DIV>\r
1467   &nbsp;\r
1468 </DIV>\r
1469 <DIV>\r
1470   The credential for planetlab.us.pl.account_test is retrieved and stored in the\r
1471   local file test.cred. The private ket test.pkey is used when opening the\r
1472   XMLRPC connection and authenticates the client. test.pkey must match the\r
1473   public key that is in the GID for the user record for\r
1474   planetlab.us.pl.account_test.\r
1475 </DIV>\r
1476 <DIV>\r
1477   &nbsp;\r
1478 </DIV>\r
1479 <DIV>\r
1480   Sample output: (in human-readable summary)\r
1481 </DIV>\r
1482 <DIV>\r
1483   &nbsp;\r
1484 </DIV>\r
1485 <DIV>\r
1486   CREDENTIAL planetlab.us.pl.account_test<BR>\r
1487   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; privs: refresh,resolve,info<BR>\r
1488   &nbsp; gidCaller:<BR>\r
1489   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; hrn:\r
1490   planetlab.us.pl.account_test<BR>\r
1491   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; uuid:\r
1492   276262316202422735940395896620385479122<BR>\r
1493   &nbsp; gidObject:<BR>\r
1494   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; hrn:\r
1495   planetlab.us.pl.account_test<BR>\r
1496   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; uuid:\r
1497   276262316202422735940395896620385479122<BR>\r
1498   &nbsp;&nbsp; delegate: False\r
1499 </DIV>\r
1500 <DIV>\r
1501   &nbsp;\r
1502 </DIV>\r
1503 <DIV>\r
1504   &nbsp;\r
1505 </DIV>\r
1506 <DIV>\r
1507   <B>5.1.2 Resolving a record</B>\r
1508 </DIV>\r
1509 <DIV>\r
1510   &nbsp;\r
1511 </DIV>\r
1512 <DIV>\r
1513   python ./genicli.py --username test resolve planetlab.us.pl.account_test\r
1514 </DIV>\r
1515 <DIV>\r
1516   &nbsp;\r
1517 </DIV>\r
1518 <DIV>\r
1519   The record for planetlab.us.pl.account_test is retrieved and printed to\r
1520   stdout. The credential used comes from the local file test.cred.\r
1521 </DIV>\r
1522 <DIV>\r
1523   &nbsp;\r
1524 </DIV>\r
1525 <DIV>\r
1526   Sample output: (in human-readable summary)\r
1527 </DIV>\r
1528 <DIV>\r
1529   &nbsp;\r
1530 </DIV>\r
1531 <DIV>\r
1532   RECORD planetlab.us.pl.account_test<BR>\r
1533   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; hrn: planetlab.us.pl.account_test<BR>\r
1534   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; type: user<BR>\r
1535   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; gid:<BR>\r
1536   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; hrn:\r
1537   planetlab.us.pl.account_test<BR>\r
1538   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; uuid:\r
1539   276262316202422735940395896620385479122<BR>\r
1540   &nbsp;&nbsp;&nbsp; pointer: 6<BR>\r
1541   &nbsp; geni_info:<BR>\r
1542   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; email :\r
1543   <A href=mailto:test@test.com>test@test.com</A><BR>\r
1544   &nbsp;&nbsp;&nbsp; pl_info:<BR>\r
1545   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bio : None<BR>\r
1546   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; first_name : test<BR>\r
1547   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; last_name : account<BR>\r
1548   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; last_updated : 1222497672<BR>\r
1549   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; uuid : None<BR>\r
1550   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; roles : ['user']<BR>\r
1551   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; title : None<BR>\r
1552   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; url : None<BR>\r
1553   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; key_ids : [1]<BR>\r
1554   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; enabled : True<BR>\r
1555   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; slice_ids : [24]<BR>\r
1556   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; phone : None<BR>\r
1557   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; peer_person_id : None<BR>\r
1558   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; role_ids : [30]<BR>\r
1559   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; person_id : 6<BR>\r
1560   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; date_created : 1219083140<BR>\r
1561   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; site_ids : [1]<BR>\r
1562   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; peer_id : None<BR>\r
1563   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; email :\r
1564   <A href=mailto:test@test.com>test@test.com</A>\r
1565 </DIV>\r
1566 <DIV>\r
1567   &nbsp;\r
1568 </DIV>\r
1569 <DIV>\r
1570   <B>5.1.3 Updating a record</B>\r
1571 </DIV>\r
1572 <DIV>\r
1573   &nbsp;\r
1574 </DIV>\r
1575 <DIV>\r
1576   python ./genicli.py --username test update user planetlab.us.pl.account_test\r
1577 </DIV>\r
1578 <DIV>\r
1579   &nbsp;\r
1580 </DIV>\r
1581 <DIV>\r
1582   The record for planetlab.us.pl.account_test is updated. The credential used\r
1583   comes from the local file test.cred. No changes are specified, so the only\r
1584   thing that should be updated is the expiration time.\r
1585 </DIV>\r
1586 <DIV>\r
1587   &nbsp;\r
1588 </DIV>\r
1589 <DIV>\r
1590   <B>5.1.4 Resolving an authority</B>\r
1591 </DIV>\r
1592 <DIV>\r
1593   &nbsp;\r
1594 </DIV>\r
1595 <DIV>\r
1596   An authority is an example of an HRN that might resolve to two different\r
1597   records, an SA and a MA record.\r
1598 </DIV>\r
1599 <DIV>\r
1600   &nbsp;\r
1601 </DIV>\r
1602 <DIV>\r
1603   python ./genicli.py --username test resolve planetlab.us.pl\r
1604 </DIV>\r
1605 <DIV>\r
1606   &nbsp;\r
1607 </DIV>\r
1608 <DIV>\r
1609   Sample Output: (in human readable summary)\r
1610 </DIV>\r
1611 <DIV>\r
1612   &nbsp;\r
1613 </DIV>\r
1614 <DIV>\r
1615   RECORD planetlab.us.pl<BR>\r
1616   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; hrn: planetlab.us.pl<BR>\r
1617   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; type: sa<BR>\r
1618   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; gid:<BR>\r
1619   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; hrn: planetlab.us.pl<BR>\r
1620   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; uuid:\r
1621   294786197975089072547582920862317666209<BR>\r
1622   &nbsp;&nbsp;&nbsp; pointer: 1<BR>\r
1623   &nbsp; geni_info:<BR>\r
1624   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pi :\r
1625   ['planetlab.us.pl.Administrator_Default']<BR>\r
1626   &nbsp;&nbsp;&nbsp; pl_info:<BR>\r
1627   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; last_updated : 1224136003<BR>\r
1628   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; node_ids : [1]<BR>\r
1629   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; site_id : 1<BR>\r
1630   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pcu_ids : []<BR>\r
1631   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; max_slices : 100<BR>\r
1632   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ext_consortium_id : None<BR>\r
1633   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; peer_site_id : None<BR>\r
1634   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; abbreviated_name : plctest<BR>\r
1635   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; uuid :\r
1636   230749975723590978208303655640765327534<BR>\r
1637   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; person_ids : [2, 4, 6]<BR>\r
1638   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; slice_ids : [24, 1, 2]<BR>\r
1639   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; latitude : None<BR>\r
1640   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; peer_id : None<BR>\r
1641   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; max_slivers : 1000<BR>\r
1642   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; is_public : False<BR>\r
1643   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; address_ids : []<BR>\r
1644   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; name : plctest Central<BR>\r
1645   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; url :\r
1646   <A href=http://198.0.0.132/>http://198.0.0.132/</A><BR>\r
1647   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; enabled : True<BR>\r
1648   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; longitude : None<BR>\r
1649   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; login_base : pl<BR>\r
1650   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; date_created : 1209428329<BR>\r
1651   RESULT:<BR>\r
1652   RECORD planetlab.us.pl<BR>\r
1653   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; hrn: planetlab.us.pl<BR>\r
1654   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; type: ma<BR>\r
1655   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; gid:<BR>\r
1656   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; hrn: planetlab.us.pl<BR>\r
1657   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; uuid:\r
1658   294786197975089072547582920862317666209<BR>\r
1659   &nbsp;&nbsp;&nbsp; pointer: 1<BR>\r
1660   &nbsp; geni_info:<BR>\r
1661   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; operator : []<BR>\r
1662   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; owner :\r
1663   ['planetlab.us.pl.Administrator_Default']<BR>\r
1664   &nbsp;&nbsp;&nbsp; pl_info:<BR>\r
1665   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; last_updated : 1224136003<BR>\r
1666   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; node_ids : [1]<BR>\r
1667   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; site_id : 1<BR>\r
1668   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pcu_ids : []<BR>\r
1669   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; max_slices : 100<BR>\r
1670   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ext_consortium_id : None<BR>\r
1671   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; peer_site_id : None<BR>\r
1672   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; abbreviated_name : plctest<BR>\r
1673   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; uuid :\r
1674   230749975723590978208303655640765327534<BR>\r
1675   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; person_ids : [2, 4, 6]<BR>\r
1676   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; slice_ids : [24, 1, 2]<BR>\r
1677   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; latitude : None<BR>\r
1678   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; peer_id : None<BR>\r
1679   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; max_slivers : 1000<BR>\r
1680   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; is_public : False<BR>\r
1681   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; address_ids : []<BR>\r
1682   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; name : plctest Central<BR>\r
1683   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; url :\r
1684   <A href=http://198.0.0.132/>http://198.0.0.132/</A><BR>\r
1685   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; enabled : True<BR>\r
1686   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; longitude : None<BR>\r
1687   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; login_base : pl<BR>\r
1688   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; date_created : 1209428329\r
1689 </DIV>\r
1690 <BR>