00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #ifdef HAVE_CONFIG_H
00030 # include <config.h>
00031 #endif
00032
00033
00034 #include "gui_p.h"
00035 #include "i18n_l.h"
00036
00037 #include <gwenhywfar/debug.h>
00038
00039
00040
00041 static GWEN_GUI *gwenhywfar_gui=NULL;
00042
00043
00044 GWEN_INHERIT_FUNCTIONS(GWEN_GUI)
00045
00046
00047
00048 GWEN_GUI *GWEN_Gui_new() {
00049 GWEN_GUI *gui;
00050
00051 GWEN_NEW_OBJECT(GWEN_GUI, gui);
00052 GWEN_INHERIT_INIT(GWEN_GUI, gui);
00053 gui->refCount=1;
00054
00055 gui->checkCertFn=GWEN_Gui_CheckCertBuiltIn;
00056
00057 return gui;
00058 }
00059
00060
00061
00062 void GWEN_Gui_free(GWEN_GUI *gui) {
00063 if (gui) {
00064 assert(gui->refCount);
00065 if ((--gui->refCount)==0) {
00066 GWEN_INHERIT_FINI(GWEN_GUI, gui);
00067 GWEN_FREE_OBJECT(gui);
00068 }
00069 }
00070 }
00071
00072
00073
00074 void GWEN_Gui_Attach(GWEN_GUI *gui) {
00075 assert(gui);
00076 assert(gui->refCount);
00077 gui->refCount++;
00078 }
00079
00080
00081
00082 void GWEN_Gui_SetGui(GWEN_GUI *gui) {
00083 if (gui)
00084 GWEN_Gui_Attach(gui);
00085 if (gwenhywfar_gui)
00086 GWEN_Gui_free(gwenhywfar_gui);
00087 gwenhywfar_gui=gui;
00088 }
00089
00090
00091
00092 GWEN_GUI *GWEN_Gui_GetGui() {
00093 return gwenhywfar_gui;
00094 }
00095
00096
00097
00098 GWEN_GUI_MESSAGEBOX_FN GWEN_Gui_SetMessageBoxFn(GWEN_GUI *gui,
00099 GWEN_GUI_MESSAGEBOX_FN f){
00100 GWEN_GUI_MESSAGEBOX_FN of;
00101
00102 assert(gui);
00103 of=gui->messageBoxFn;
00104 gui->messageBoxFn=f;
00105 return of;
00106 }
00107
00108
00109
00110 GWEN_GUI_INPUTBOX_FN GWEN_Gui_SetInputBoxFn(GWEN_GUI *gui,
00111 GWEN_GUI_INPUTBOX_FN f){
00112 GWEN_GUI_INPUTBOX_FN of;
00113
00114 assert(gui);
00115 of=gui->inputBoxFn;
00116 gui->inputBoxFn=f;
00117 return of;
00118 }
00119
00120
00121
00122 GWEN_GUI_SHOWBOX_FN GWEN_Gui_SetShowBoxFn(GWEN_GUI *gui,
00123 GWEN_GUI_SHOWBOX_FN f){
00124 GWEN_GUI_SHOWBOX_FN of;
00125
00126 assert(gui);
00127 of=gui->showBoxFn;
00128 gui->showBoxFn=f;
00129 return of;
00130 }
00131
00132
00133
00134 GWEN_GUI_HIDEBOX_FN GWEN_Gui_SetHideBoxFn(GWEN_GUI *gui,
00135 GWEN_GUI_HIDEBOX_FN f){
00136 GWEN_GUI_HIDEBOX_FN of;
00137
00138 assert(gui);
00139 of=gui->hideBoxFn;
00140 gui->hideBoxFn=f;
00141 return of;
00142 }
00143
00144
00145
00146 GWEN_GUI_PROGRESS_START_FN
00147 GWEN_Gui_SetProgressStartFn(GWEN_GUI *gui, GWEN_GUI_PROGRESS_START_FN f){
00148 GWEN_GUI_PROGRESS_START_FN of;
00149
00150 assert(gui);
00151 of=gui->progressStartFn;
00152 gui->progressStartFn=f;
00153 return of;
00154 }
00155
00156
00157
00158 GWEN_GUI_PROGRESS_ADVANCE_FN
00159 GWEN_Gui_SetProgressAdvanceFn(GWEN_GUI *gui, GWEN_GUI_PROGRESS_ADVANCE_FN f){
00160 GWEN_GUI_PROGRESS_ADVANCE_FN of;
00161
00162 assert(gui);
00163 of=gui->progressAdvanceFn;
00164 gui->progressAdvanceFn=f;
00165 return of;
00166 }
00167
00168
00169
00170 GWEN_GUI_PROGRESS_LOG_FN
00171 GWEN_Gui_SetProgressLogFn(GWEN_GUI *gui, GWEN_GUI_PROGRESS_LOG_FN f){
00172 GWEN_GUI_PROGRESS_LOG_FN of;
00173
00174 assert(gui);
00175 of=gui->progressLogFn;
00176 gui->progressLogFn=f;
00177 return of;
00178 }
00179
00180
00181
00182 GWEN_GUI_PROGRESS_END_FN
00183 GWEN_Gui_SetProgressEndFn(GWEN_GUI *gui, GWEN_GUI_PROGRESS_END_FN f){
00184 GWEN_GUI_PROGRESS_END_FN of;
00185
00186 assert(gui);
00187 of=gui->progressEndFn;
00188 gui->progressEndFn=f;
00189 return of;
00190 }
00191
00192
00193
00194 GWEN_GUI_PRINT_FN GWEN_Gui_SetPrintFn(GWEN_GUI *gui,
00195 GWEN_GUI_PRINT_FN f){
00196 GWEN_GUI_PRINT_FN of;
00197
00198 assert(gui);
00199 of=gui->printFn;
00200 gui->printFn=f;
00201 return of;
00202 }
00203
00204
00205
00206 GWEN_GUI_GETPASSWORD_FN GWEN_Gui_SetGetPasswordFn(GWEN_GUI *gui,
00207 GWEN_GUI_GETPASSWORD_FN f) {
00208 GWEN_GUI_GETPASSWORD_FN of;
00209
00210 assert(gui);
00211 of=gui->getPasswordFn;
00212 gui->getPasswordFn=f;
00213 return of;
00214 }
00215
00216
00217
00218 GWEN_GUI_SETPASSWORDSTATUS_FN
00219 GWEN_Gui_SetSetPasswordStatusFn(GWEN_GUI *gui,
00220 GWEN_GUI_SETPASSWORDSTATUS_FN f) {
00221 GWEN_GUI_SETPASSWORDSTATUS_FN of;
00222
00223 assert(gui);
00224 of=gui->setPasswordStatusFn;
00225 gui->setPasswordStatusFn=f;
00226 return of;
00227 }
00228
00229
00230
00231 GWEN_GUI_LOG_HOOK_FN GWEN_Gui_SetLogHookFn(GWEN_GUI *gui,
00232 GWEN_GUI_LOG_HOOK_FN f) {
00233 GWEN_GUI_LOG_HOOK_FN of;
00234
00235 assert(gui);
00236 of=gui->logHookFn;
00237 gui->logHookFn=f;
00238
00239 return of;
00240 }
00241
00242
00243
00244 GWEN_GUI_WAITFORSOCKETS_FN GWEN_Gui_SetWaitForSocketsFn(GWEN_GUI *gui,
00245 GWEN_GUI_WAITFORSOCKETS_FN f) {
00246 GWEN_GUI_WAITFORSOCKETS_FN of;
00247
00248 assert(gui);
00249 of=gui->waitForSocketsFn;
00250 gui->waitForSocketsFn=f;
00251
00252 return of;
00253 }
00254
00255
00256
00257 GWEN_GUI_CHECKCERT_FN GWEN_Gui_SetCheckCertFn(GWEN_GUI *gui, GWEN_GUI_CHECKCERT_FN f) {
00258 GWEN_GUI_CHECKCERT_FN of;
00259
00260 assert(gui);
00261 of=gui->checkCertFn;
00262 gui->checkCertFn=f;
00263
00264 return of;
00265 }
00266
00267
00268
00269 GWEN_GUI_KEYDATAFROMTEXT_OPENSSL_FN
00270 GWEN_Gui_SetKeyDataFromTextOpenSslFn(GWEN_GUI *gui,
00271 GWEN_GUI_KEYDATAFROMTEXT_OPENSSL_FN f) {
00272 GWEN_GUI_KEYDATAFROMTEXT_OPENSSL_FN of;
00273
00274 assert(gui);
00275 of=gui->keyDataFromTextOpenSslFn;
00276 gui->keyDataFromTextOpenSslFn=f;
00277
00278 return of;
00279
00280 }
00281
00282
00283
00284
00285
00286
00287
00288 int GWEN_Gui_MessageBox(uint32_t flags,
00289 const char *title,
00290 const char *text,
00291 const char *b1,
00292 const char *b2,
00293 const char *b3,
00294 uint32_t guiid) {
00295 if (gwenhywfar_gui && gwenhywfar_gui->messageBoxFn)
00296 return gwenhywfar_gui->messageBoxFn(gwenhywfar_gui,
00297 flags,
00298 title,
00299 text,
00300 b1, b2, b3, guiid);
00301 return GWEN_ERROR_NOT_IMPLEMENTED;
00302 }
00303
00304
00305
00306 int GWEN_Gui_InputBox(uint32_t flags,
00307 const char *title,
00308 const char *text,
00309 char *buffer,
00310 int minLen,
00311 int maxLen,
00312 uint32_t guiid) {
00313 if (gwenhywfar_gui && gwenhywfar_gui->inputBoxFn)
00314 return gwenhywfar_gui->inputBoxFn(gwenhywfar_gui,
00315 flags,
00316 title,
00317 text,
00318 buffer,
00319 minLen, maxLen, guiid);
00320 return GWEN_ERROR_NOT_IMPLEMENTED;
00321 }
00322
00323
00324
00325 uint32_t GWEN_Gui_ShowBox(uint32_t flags,
00326 const char *title,
00327 const char *text,
00328 uint32_t guiid) {
00329 if (gwenhywfar_gui && gwenhywfar_gui->showBoxFn)
00330 return gwenhywfar_gui->showBoxFn(gwenhywfar_gui,
00331 flags,
00332 title,
00333 text,
00334 guiid);
00335 return 0;
00336 }
00337
00338
00339
00340 void GWEN_Gui_HideBox(uint32_t id) {
00341 if (gwenhywfar_gui && gwenhywfar_gui->hideBoxFn)
00342 return gwenhywfar_gui->hideBoxFn(gwenhywfar_gui, id);
00343 }
00344
00345
00346
00347 uint32_t GWEN_Gui_ProgressStart(uint32_t progressFlags,
00348 const char *title,
00349 const char *text,
00350 uint64_t total,
00351 uint32_t guiid) {
00352 if (gwenhywfar_gui && gwenhywfar_gui->progressStartFn)
00353 return gwenhywfar_gui->progressStartFn(gwenhywfar_gui,
00354 progressFlags,
00355 title,
00356 text,
00357 total,
00358 guiid);
00359 return 0;
00360 }
00361
00362
00363
00364 int GWEN_Gui_ProgressAdvance(uint32_t id, uint32_t progress) {
00365 if (gwenhywfar_gui && gwenhywfar_gui->progressAdvanceFn)
00366 return gwenhywfar_gui->progressAdvanceFn(gwenhywfar_gui,
00367 id,
00368 progress);
00369 return 0;
00370 }
00371
00372
00373
00374 int GWEN_Gui_ProgressLog(uint32_t id,
00375 GWEN_LOGGER_LEVEL level,
00376 const char *text) {
00377 if (gwenhywfar_gui && gwenhywfar_gui->progressLogFn)
00378 return gwenhywfar_gui->progressLogFn(gwenhywfar_gui,
00379 id, level, text);
00380 return 0;
00381 }
00382
00383
00384
00385 int GWEN_Gui_ProgressEnd(uint32_t id) {
00386 if (gwenhywfar_gui && gwenhywfar_gui->progressEndFn)
00387 return gwenhywfar_gui->progressEndFn(gwenhywfar_gui, id);
00388 return GWEN_ERROR_NOT_IMPLEMENTED;
00389 }
00390
00391
00392
00393 int GWEN_Gui_Print(const char *docTitle,
00394 const char *docType,
00395 const char *descr,
00396 const char *text,
00397 uint32_t guiid) {
00398 if (gwenhywfar_gui && gwenhywfar_gui->printFn)
00399 return gwenhywfar_gui->printFn(gwenhywfar_gui,
00400 docTitle,
00401 docType,
00402 descr,
00403 text,
00404 guiid);
00405 return GWEN_ERROR_NOT_IMPLEMENTED;
00406 }
00407
00408
00409
00410 int GWEN_Gui_GetPassword(uint32_t flags,
00411 const char *token,
00412 const char *title,
00413 const char *text,
00414 char *buffer,
00415 int minLen,
00416 int maxLen,
00417 uint32_t guiid) {
00418 if (gwenhywfar_gui) {
00419 if (gwenhywfar_gui->getPasswordFn)
00420 return gwenhywfar_gui->getPasswordFn(gwenhywfar_gui,
00421 flags,
00422 token,
00423 title,
00424 text,
00425 buffer,
00426 minLen,
00427 maxLen,
00428 guiid);
00429 else
00430 return gwenhywfar_gui->inputBoxFn(gwenhywfar_gui,
00431 flags,
00432 title,
00433 text,
00434 buffer,
00435 minLen,
00436 maxLen,
00437 guiid);
00438 }
00439 return GWEN_ERROR_NOT_IMPLEMENTED;
00440 }
00441
00442
00443
00444 int GWEN_Gui_SetPasswordStatus(const char *token,
00445 const char *pin,
00446 GWEN_GUI_PASSWORD_STATUS status,
00447 uint32_t guiid) {
00448 if (gwenhywfar_gui && gwenhywfar_gui->setPasswordStatusFn)
00449 return gwenhywfar_gui->setPasswordStatusFn(gwenhywfar_gui,
00450 token, pin, status, guiid);
00451 return GWEN_ERROR_NOT_IMPLEMENTED;
00452 }
00453
00454
00455
00456 int GWEN_Gui_LogHook(const char *logDomain,
00457 GWEN_LOGGER_LEVEL priority, const char *s) {
00458 if (gwenhywfar_gui && gwenhywfar_gui->logHookFn)
00459 return gwenhywfar_gui->logHookFn(gwenhywfar_gui, logDomain, priority, s);
00460 else
00461
00462 return 0;
00463 }
00464
00465
00466
00467 int GWEN_Gui_WaitForSockets(GWEN_SOCKET_LIST2 *readSockets,
00468 GWEN_SOCKET_LIST2 *writeSockets,
00469 uint32_t guiid,
00470 int msecs) {
00471 if (gwenhywfar_gui && gwenhywfar_gui->waitForSocketsFn)
00472 return gwenhywfar_gui->waitForSocketsFn(gwenhywfar_gui, readSockets, writeSockets, guiid, msecs);
00473 else {
00474 GWEN_SOCKETSET *rset;
00475 GWEN_SOCKETSET *wset;
00476 GWEN_SOCKET_LIST2_ITERATOR *sit;
00477
00478 rset=GWEN_SocketSet_new();
00479 wset=GWEN_SocketSet_new();
00480
00481
00482 sit=GWEN_Socket_List2_First(readSockets);
00483 if (sit) {
00484 GWEN_SOCKET *s;
00485
00486 s=GWEN_Socket_List2Iterator_Data(sit);
00487 assert(s);
00488
00489 while(s) {
00490 GWEN_SocketSet_AddSocket(rset, s);
00491 s=GWEN_Socket_List2Iterator_Next(sit);
00492 }
00493 GWEN_Socket_List2Iterator_free(sit);
00494 }
00495
00496
00497 sit=GWEN_Socket_List2_First(writeSockets);
00498 if (sit) {
00499 GWEN_SOCKET *s;
00500
00501 s=GWEN_Socket_List2Iterator_Data(sit);
00502 assert(s);
00503
00504 while(s) {
00505 GWEN_SocketSet_AddSocket(wset, s);
00506 s=GWEN_Socket_List2Iterator_Next(sit);
00507 }
00508 GWEN_Socket_List2Iterator_free(sit);
00509 }
00510
00511 if (GWEN_SocketSet_GetSocketCount(rset)==0 &&
00512 GWEN_SocketSet_GetSocketCount(wset)==0) {
00513
00514 GWEN_SocketSet_free(wset);
00515 GWEN_SocketSet_free(rset);
00516
00517 if (msecs) {
00518
00519 DBG_DEBUG(GWEN_LOGDOMAIN, "Sleeping (no socket)");
00520 GWEN_Socket_Select(NULL, NULL, NULL, GWEN_GUI_CPU_TIMEOUT);
00521 }
00522 return GWEN_ERROR_TIMEOUT;
00523 }
00524 else {
00525 int rv;
00526
00527 rv=GWEN_Socket_Select(rset, wset, NULL, msecs);
00528 GWEN_SocketSet_free(wset);
00529 GWEN_SocketSet_free(rset);
00530
00531 return rv;
00532 }
00533 }
00534 }
00535
00536
00537
00538 int GWEN_Gui_CheckCert(const GWEN_SSLCERTDESCR *cd, GWEN_IO_LAYER *io, uint32_t guiid) {
00539 if (gwenhywfar_gui && gwenhywfar_gui->checkCertFn)
00540 return gwenhywfar_gui->checkCertFn(gwenhywfar_gui, cd, io, guiid);
00541 else
00542 return GWEN_ERROR_NOT_IMPLEMENTED;
00543 }
00544
00545
00546
00547 int GWEN_Gui_CheckCertBuiltIn(GWEN_GUI *gui,
00548 const GWEN_SSLCERTDESCR *cd,
00549 GWEN_IO_LAYER *io, uint32_t guiid) {
00550 int rv;
00551 int isError;
00552 const char *hash;
00553 const char *status;
00554 const char *ipAddr;
00555 const char *statusOn;
00556 const char *statusOff;
00557 char varName[128];
00558 char dbuffer1[32];
00559 char dbuffer2[32];
00560 char buffer[8192];
00561 const GWEN_TIME *ti;
00562 const char *unknown;
00563 const char *commonName;
00564 const char *organizationName;
00565 const char *organizationalUnitName;
00566 const char *countryName;
00567 const char *localityName;
00568 const char *stateOrProvinceName;
00569
00570 char *msg=I18S(
00571 "The following certificate has been received:\n"
00572 "Name : %s\n"
00573 "Organisation: %s\n"
00574 "Department : %s\n"
00575 "Country : %s\n"
00576 "City : %s\n"
00577 "State : %s\n"
00578 "Valid after : %s\n"
00579 "Valid until : %s\n"
00580 "Hash : %s\n"
00581 "Status : %s\n"
00582 "Do you wish to accept this certificate?"
00583
00584 "<html>"
00585 " <p>"
00586 " The following certificate has been received:"
00587 " </p>"
00588 " <table>"
00589 " <tr><td>Name</td><td>%s</td></tr>"
00590 " <tr><td>Organisation</td><td>%s</td></tr>"
00591 " <tr><td>Department</td><td>%s</td></tr>"
00592 " <tr><td>Country</td><td>%s</td></tr>"
00593 " <tr><td>City</td><td>%s</td></tr>"
00594 " <tr><td>State</td><td>%s</td></tr>"
00595 " <tr><td>Valid after</td><td>%s</td></tr>"
00596 " <tr><td>Valid until</td><td>%s</td></tr>"
00597 " <tr><td>Hash</td><td>%s</td></tr>"
00598 " <tr><td>Status</td><td>%s%s%s</td></tr>"
00599 " </table>"
00600 " <p>"
00601 " Do you wish to accept this certificate?"
00602 " </p>"
00603 "</html>"
00604 );
00605
00606 memset(dbuffer1, 0, sizeof(dbuffer1));
00607 memset(dbuffer2, 0, sizeof(dbuffer2));
00608 memset(varName, 0, sizeof(varName));
00609
00610 isError=GWEN_SslCertDescr_GetIsError(cd);
00611
00612 hash=GWEN_SslCertDescr_GetFingerPrint(cd);
00613 status=GWEN_SslCertDescr_GetStatusText(cd);
00614 ipAddr=GWEN_SslCertDescr_GetIpAddress(cd);
00615
00616 ti=GWEN_SslCertDescr_GetNotBefore(cd);
00617 if (ti) {
00618 GWEN_BUFFER *tbuf;
00619
00620 tbuf=GWEN_Buffer_new(0, 32, 0, 1);
00621
00622
00623
00624
00625
00626
00627 if (GWEN_Time_toString(ti, I18N("YYYY/MM/DD hh:mm:ss"), tbuf)) {
00628 DBG_ERROR(GWEN_LOGDOMAIN,
00629 "Could not convert beforeDate to string");
00630 abort();
00631 }
00632 strncpy(dbuffer1, GWEN_Buffer_GetStart(tbuf), sizeof(dbuffer1)-1);
00633 GWEN_Buffer_free(tbuf);
00634 }
00635
00636 ti=GWEN_SslCertDescr_GetNotAfter(cd);
00637 if (ti) {
00638 GWEN_BUFFER *tbuf;
00639
00640 tbuf=GWEN_Buffer_new(0, 32, 0, 1);
00641 if (GWEN_Time_toString(ti, I18N("YYYY/MM/DD hh:mm:ss"), tbuf)) {
00642 DBG_ERROR(GWEN_LOGDOMAIN,
00643 "Could not convert untilDate to string");
00644 abort();
00645 }
00646 strncpy(dbuffer2, GWEN_Buffer_GetStart(tbuf), sizeof(dbuffer2)-1);
00647 GWEN_Buffer_free(tbuf);
00648 }
00649
00650 if (isError) {
00651 statusOn="<font color=red>";
00652 statusOff="</font>";
00653 }
00654 else {
00655 statusOn="<font color=green>";
00656 statusOff="</font>";
00657 }
00658
00659 unknown=I18N("unknown");
00660 commonName=GWEN_SslCertDescr_GetCommonName(cd);
00661 if (!commonName)
00662 commonName=unknown;
00663 organizationName=GWEN_SslCertDescr_GetOrganizationName(cd);
00664 if (!organizationName)
00665 organizationName=unknown;
00666 organizationalUnitName=GWEN_SslCertDescr_GetOrganizationalUnitName(cd);
00667 if (!organizationalUnitName)
00668 organizationalUnitName=unknown;
00669 countryName=GWEN_SslCertDescr_GetCountryName(cd);
00670 if (!countryName)
00671 countryName=unknown;
00672 localityName=GWEN_SslCertDescr_GetLocalityName(cd);
00673 if (!localityName)
00674 localityName=unknown;
00675 stateOrProvinceName=GWEN_SslCertDescr_GetStateOrProvinceName(cd);
00676 if (!stateOrProvinceName)
00677 stateOrProvinceName=unknown;
00678 if (!status)
00679 status=unknown;
00680
00681 snprintf(buffer, sizeof(buffer)-1,
00682 I18N(msg),
00683 commonName,
00684 organizationName,
00685 organizationalUnitName,
00686 countryName,
00687 localityName,
00688 stateOrProvinceName,
00689 dbuffer1, dbuffer2,
00690 hash,
00691 status,
00692
00693 commonName,
00694 organizationName,
00695 organizationalUnitName,
00696 countryName,
00697 localityName,
00698 stateOrProvinceName,
00699 dbuffer1, dbuffer2,
00700 hash,
00701 statusOn,
00702 status,
00703 statusOff
00704 );
00705
00706 rv=GWEN_Gui_MessageBox(GWEN_GUI_MSG_FLAGS_TYPE_WARN |
00707 GWEN_GUI_MSG_FLAGS_CONFIRM_B1 |
00708 GWEN_GUI_MSG_FLAGS_SEVERITY_DANGEROUS,
00709 I18N("Certificate Received"),
00710 buffer,
00711 I18N("Yes"), I18N("No"), 0, guiid);
00712 if (rv==1) {
00713 return 0;
00714 }
00715 else {
00716 DBG_NOTICE(GWEN_LOGDOMAIN, "User rejected certificate");
00717
00718 return GWEN_ERROR_SSL_SECURITY;
00719 }
00720 }
00721
00722
00723
00724 int GWEN_Gui_KeyDataFromText_OpenSSL(const char *text,
00725 unsigned char *buffer,
00726 unsigned int bufLength) {
00727 if (gwenhywfar_gui && gwenhywfar_gui->keyDataFromTextOpenSslFn)
00728 return gwenhywfar_gui->keyDataFromTextOpenSslFn(gwenhywfar_gui,
00729 text,
00730 buffer,
00731 bufLength);
00732 return GWEN_ERROR_NOT_IMPLEMENTED;
00733 }
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749