00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <stdio.h>
00022 #include <string.h>
00023 #include <stdlib.h>
00024 #include <unistd.h>
00025 #include <pwd.h>
00026 #include <fcntl.h>
00027 #include <sys/stat.h>
00028 #include <errno.h>
00029
00030 #include "rpdp.h"
00031
00032
00033 extern int gDebug;
00034
00035 namespace ROOT {
00036
00037
00038
00039
00040
00041 void GlbsToolError(char *msg, int maj, int min, int tok)
00042 {
00043
00044
00045 char *e = 0;
00046
00047 if (globus_gss_assist_display_status_str(&e, msg, maj, min, tok) || !e) {
00048 ErrorInfo("Error: %s: error messaged not resolved"
00049 " (majst=%d,minst=%d,tokst:%d)", msg, maj, min, tok);
00050 } else {
00051 ErrorInfo("Error: %s (majst=%d,minst=%d,tokst:%d)", e, maj, min, tok);
00052 delete [] e;
00053 }
00054 NetSend(kErrFatal, kROOTD_ERR);
00055 }
00056
00057
00058 int GlbsToolCheckCert(char **subjname)
00059 {
00060
00061
00062
00063
00064 if (gDebug > 2)
00065 ErrorInfo("GlbsToolCheckCert: enter");
00066
00067
00068 std::string hcconf = "/hostcert.conf";
00069 if (getenv("ROOTHOSTCERT")) {
00070 hcconf = getenv("ROOTHOSTCERT");
00071 } else {
00072 if (getenv("ROOTETCDIR"))
00073 hcconf.insert(0,getenv("ROOTETCDIR"));
00074 else
00075 hcconf.insert(0,"/etc/root");
00076 }
00077
00078
00079 hcconf[hcconf.length()] = 0;
00080
00081 std::string fns[4];
00082 FILE *fconf = 0;
00083 if ((fconf = fopen(hcconf.data(), "r"))) {
00084 char line[kMAXPATHLEN];
00085 if (gDebug > 2)
00086 ErrorInfo("GlbsToolCheckCert: reading file %s", hcconf.c_str());
00087
00088
00089 while (fgets(line, sizeof(line), fconf)) {
00090 if (line[0] == '#') continue;
00091 if (strlen(line) == 0) continue;
00092 if (line[strlen(line)-1] == '\n')
00093 line[strlen(line)-1] = '\0';
00094 int i = 0;
00095 char *p0 = &line[0];
00096 char *p1 = p0;
00097 while ((p1 = strchr(p0+1, ' '))) {
00098 *p1 = '\0';
00099 fns[i++] = p0;
00100 p1++;
00101 while (p1[0] == ' ')
00102 p1++;
00103 p0 = p1;
00104 }
00105
00106 if (i < 4) fns[i++] = p0;
00107
00108 while (i < 4)
00109 fns[i++] = "*";
00110 }
00111 fclose(fconf);
00112 if (gDebug > 2)
00113 ErrorInfo("GlbsToolCheckCert: from file: {%s,%s,%s,%s}",
00114 fns[0].c_str(), fns[1].c_str(), fns[2].c_str(), fns[3].c_str());
00115 } else {
00116
00117 int i = 0;
00118 while (i < 4)
00119 fns[i++] = "*";
00120 }
00121
00122
00123 int rdir = 0, rcer = 0;
00124
00125
00126 std::string dir = fns[0];
00127 if (access(dir.c_str(), R_OK)) {
00128
00129 dir = "/etc/grid-security/certificates";
00130 if (access(dir.c_str(), R_OK)) {
00131
00132 if (gDebug > 0)
00133 ErrorInfo("GlbsToolCheckCert: no readable certificate dir found");
00134 rdir = 1;
00135 }
00136 }
00137 if (!rdir)
00138 if ((rdir = setenv("X509_CERT_DIR", dir.c_str(), 1)))
00139 ErrorInfo("GlbsToolCheckCert: unable to set X509_CERT_DIR ");
00140
00141
00142 std::string map = fns[3];
00143 if (access(map.c_str(), R_OK)) {
00144
00145 map = "/etc/grid-security/grid-mapfile";
00146 if (access(map.c_str(), R_OK)) {
00147
00148 if (gDebug > 0)
00149 ErrorInfo("GlbsToolCheckCert: no readable grid-mapfile found");
00150 rdir = 1;
00151 }
00152 }
00153 if (!rdir)
00154 if ((rdir = setenv("GRIDMAP", map.c_str(), 1)))
00155 ErrorInfo("GlbsToolCheckCert: unable to set GRIDMAP ");
00156
00157
00158 std::string cert = fns[1];
00159 std::string key = fns[2];
00160 if (access(cert.c_str(), R_OK) || access(key.c_str(), R_OK)) {
00161
00162 cert = "/etc/grid-security/root/rootcert.pem";
00163 key = "/etc/grid-security/root/rootkey.pem";
00164 if (access(cert.c_str(), R_OK) || access(key.c_str(), R_OK)) {
00165
00166 cert = "/etc/grid-security/hostcert.pem";
00167 key = "/etc/grid-security/hostkey.pem";
00168 if (access(cert.c_str(), R_OK) || access(key.c_str(), R_OK)) {
00169
00170 if (gDebug > 0)
00171 ErrorInfo("GlbsToolCheckCert: no readable {cert, key} pair found");
00172 rcer = 1;
00173 }
00174 }
00175 }
00176 if (!rcer) {
00177
00178 if ((rcer = setenv("X509_USER_CERT", cert.c_str(), 1)))
00179 ErrorInfo("GlbsToolCheckCert: unable to set X509_HOST_CERT ");
00180 if ((rcer = setenv("X509_USER_KEY", key.c_str(), 1)))
00181 ErrorInfo("GlbsToolCheckCert: unable to set X509_HOST_KEY ");
00182
00183
00184 FILE *fcert = fopen(cert.c_str(), "r");
00185 X509 *xcert = 0;
00186 if (!PEM_read_X509(fcert, &xcert, 0, 0)) {
00187 ErrorInfo("GlbsToolCheckCert: unable to load certificate from %s",
00188 cert.c_str());
00189 rcer = 1;
00190 } else {
00191 *subjname = X509_NAME_oneline(X509_get_subject_name(xcert), 0, 0);
00192 if (gDebug > 2)
00193 ErrorInfo("GlbsToolCheckCert: subject: %s", *subjname);
00194 }
00195 }
00196
00197
00198 if (!rdir && !rcer)
00199 if (gDebug > 2)
00200 ErrorInfo("GlbsToolCheckCert: using: {%s,%s,%s,%s}",
00201 dir.c_str(), cert.c_str(), key.c_str(), map.c_str());
00202
00203
00204 return ((rdir != 0 || rcer != 0) ? 1 : 0);
00205 }
00206
00207
00208 int GlbsToolCheckContext(int shmId)
00209 {
00210
00211
00212
00213 int retval = 0;
00214 OM_uint32 majstat = 0;
00215 OM_uint32 minstat = 0;
00216 gss_ctx_id_t context_handle = GSS_C_NO_CONTEXT;
00217 OM_uint32 gssRetFlags = 0;
00218 OM_uint32 glbContLifeTime = 0;
00219 int dum1, dum2;
00220 gss_OID mechType;
00221 gss_name_t *targname = 0, *name = 0;
00222
00223 if (gDebug > 2)
00224 ErrorInfo("GlbsToolCheckContext: checking contetx in shm : %d",
00225 shmId);
00226
00227
00228 gss_buffer_t databuf = (gss_buffer_t) shmat(shmId, 0, 0);
00229 if (gDebug > 2)
00230 ErrorInfo
00231 ("GlbsToolCheckContext: retrieving info from shared memory: %d",
00232 shmId);
00233
00234
00235 gss_buffer_t secContExp =
00236 (gss_buffer_t) new char[sizeof(gss_buffer_desc) + databuf->length];
00237 secContExp->length = databuf->length;
00238 secContExp->value =
00239 (void *) ((char *) secContExp + sizeof(size_t) + sizeof(void *));
00240 void *dbufval =
00241 (void *) ((char *) databuf + sizeof(size_t) + sizeof(void *));
00242 memmove(secContExp->value, dbufval, secContExp->length);
00243 if ((majstat =
00244 gss_import_sec_context(&minstat, secContExp,
00245 &context_handle)) != GSS_S_COMPLETE) {
00246 GlbsToolError("GlbsToolCheckContext: gss_import_sec_context",
00247 majstat, minstat, 0);
00248 } else if (gDebug > 2)
00249 ErrorInfo
00250 ("GlbsToolCheckContext: GlbsTool Sec Context successfully imported (0x%x)",
00251 context_handle);
00252
00253 delete[]secContExp;
00254
00255
00256 int rc = shmdt((const void *) databuf);
00257 if (rc != 0) {
00258 ErrorInfo
00259 ("GlbsToolCheckContext: unable to detach from shared memory segment %d (rc=%d)",
00260 shmId, rc);
00261 }
00262
00263 if (context_handle != 0 && context_handle != GSS_C_NO_CONTEXT) {
00264 if ((majstat =
00265 gss_inquire_context(&minstat, context_handle, name, targname,
00266 &glbContLifeTime, &mechType, &gssRetFlags,
00267 &dum1, &dum2)) != GSS_S_COMPLETE) {
00268 GlbsToolError("GlbsToolCheckContext: gss_inquire_context",
00269 majstat, minstat, 0);
00270
00271 struct shmid_ds shm_ds;
00272 if (!shmctl(shmId, IPC_RMID, &shm_ds))
00273 ErrorInfo
00274 ("GlbsToolCheckContext: unable to mark shared memory segment %d for desctruction",
00275 shmId);
00276 } else {
00277 if (gDebug > 2)
00278 ErrorInfo
00279 ("GlbsToolCheckContext: found valid context in shm %d",
00280 shmId);
00281 retval = 1;
00282 }
00283 }
00284
00285 return retval;
00286 }
00287
00288
00289 int GlbsToolStoreContext(gss_ctx_id_t context_handle, char *user)
00290 {
00291
00292
00293
00294
00295 OM_uint32 majstat;
00296 OM_uint32 minstat;
00297 key_t shm_key = IPC_PRIVATE;
00298 int shm_flg = 0777;
00299 struct shmid_ds shm_ds;
00300
00301 if (gDebug > 2)
00302 ErrorInfo("GlbsToolStoreContext: Enter");
00303
00304
00305 gss_buffer_t secContExp = new gss_buffer_desc;
00306 if ((majstat =
00307 gss_export_sec_context(&minstat, &context_handle,
00308 secContExp)) != GSS_S_COMPLETE) {
00309 GlbsToolError("GlbsToolStoreContext: gss_export_sec_context",
00310 majstat, minstat, 0);
00311 gss_release_buffer(&minstat,secContExp);
00312 delete secContExp;
00313 return 0;
00314 } else if (gDebug > 2)
00315 ErrorInfo
00316 ("GlbsToolStoreContext: security context prepared for export");
00317
00318
00319 int shm_size = sizeof(gss_buffer_desc) + secContExp->length;
00320 if (gDebug > 2)
00321 ErrorInfo
00322 ("GlbsToolStoreContext: needed shared memory segment sizes: %d",
00323 shm_size);
00324
00325
00326 int shmId = shmget(shm_key, shm_size, shm_flg);
00327 if (shmId < 0) {
00328 ErrorInfo
00329 ("GlbsToolStoreContext: while allocating shared memory segment (rc=%d)",
00330 shmId);
00331 gss_release_buffer(&minstat,secContExp);
00332 delete secContExp;
00333 return 0;
00334 } else if (gDebug > 2)
00335 ErrorInfo
00336 ("GlbsToolStoreContext: shared memory segment allocated (id=%d)",
00337 shmId);
00338
00339
00340 gss_buffer_t databuf = (gss_buffer_t) shmat(shmId, 0, 0);
00341 if (databuf == (gss_buffer_t)(-1)) {
00342 ErrorInfo("GlbsToolStoreContext: while attaching to shared memory"
00343 " segment (rc=%d)", shmId);
00344 gss_release_buffer(&minstat,secContExp);
00345 shmctl(shmId, IPC_RMID, &shm_ds);
00346 return 0;
00347 }
00348 databuf->length = secContExp->length;
00349 databuf->value =
00350 (void *) ((char *) databuf + sizeof(size_t) + sizeof(void *));
00351 memmove(databuf->value, secContExp->value, secContExp->length);
00352
00353
00354
00355 int rc = 0;
00356 if ((rc = shmdt((const void *) databuf)) != 0) {
00357 ErrorInfo
00358 ("GlbsToolStoreContext: unable to detach from shared memory segment (rc=%d)",
00359 rc);
00360 }
00361
00362
00363 if ((majstat = gss_release_buffer(&minstat, secContExp)) != GSS_S_COMPLETE)
00364 GlbsToolError("GlbsToolStoreContext: gss_release_buffer",
00365 majstat, minstat, 0);
00366 delete secContExp;
00367
00368
00369
00370 if (shmctl(shmId, IPC_STAT, &shm_ds) == -1) {
00371 ErrorInfo
00372 ("GlbsToolStoreContext: can't get info about shared memory segment %d",
00373 shmId);
00374 shmctl(shmId, IPC_RMID, &shm_ds);
00375 return 0;
00376 }
00377
00378 struct passwd *pw = getpwnam(user);
00379
00380 if (pw) {
00381
00382 shm_ds.shm_perm.uid = pw->pw_uid;
00383 shm_ds.shm_perm.gid = pw->pw_gid;
00384 if (shmctl(shmId, IPC_SET, &shm_ds) == -1) {
00385 ErrorInfo
00386 ("GlbsToolStoreContext: can't change ownership of shared memory segment %d",
00387 shmId);
00388 shmctl(shmId, IPC_RMID, &shm_ds);
00389 return 0;
00390 }
00391 } else {
00392 ErrorInfo
00393 ("GlbsToolStoreContext: user %s unknown to the system!", user);
00394 }
00395
00396 return shmId;
00397 }
00398
00399
00400 int GlbsToolStoreToShm(gss_buffer_t buffer, int *shmId)
00401 {
00402
00403
00404
00405 key_t shm_key = IPC_PRIVATE;
00406 int shm_flg = 0777;
00407 struct shmid_ds shm_ds;
00408
00409 if (gDebug > 2)
00410 ErrorInfo("GlbsToolStoreToShm: Enter: shmId: %d", *shmId);
00411
00412
00413 int shm_size = sizeof(gss_buffer_desc) + buffer->length;
00414 if (gDebug > 2)
00415 ErrorInfo
00416 ("GlbsToolStoreToShm: needed shared memory segment sizes: %d",
00417 shm_size);
00418
00419
00420 int lshmId = shmget(shm_key, shm_size, shm_flg);
00421 if (lshmId < 0) {
00422 ErrorInfo
00423 ("GlbsToolStoreToShm: while allocating shared memory segment (rc=%d)",
00424 lshmId);
00425 return 1;
00426 } else if (gDebug > 2)
00427 ErrorInfo
00428 ("GlbsToolStoreToShm: shared memory segment allocated (id=%d)",
00429 lshmId);
00430
00431 *shmId = lshmId;
00432
00433
00434 gss_buffer_t databuf = (gss_buffer_t) shmat(lshmId, 0, 0);
00435 if (databuf == (gss_buffer_t)(-1)) {
00436 ErrorInfo("GlbsToolStoreToShm: while attaching to shared memory"
00437 " segment (rc=%d)", lshmId);
00438 shmctl(lshmId, IPC_RMID, &shm_ds);
00439 return 2;
00440 }
00441 databuf->length = buffer->length;
00442 databuf->value =
00443 (void *) ((char *) databuf + sizeof(size_t) + sizeof(void *));
00444 memmove(databuf->value, buffer->value, buffer->length);
00445
00446
00447 int rc = 0;
00448 if ((rc = shmdt((const void *) databuf)) != 0) {
00449 ErrorInfo
00450 ("GlbsToolStoreToShm: unable to detach from shared memory segment (rc=%d)",
00451 rc);
00452 }
00453 return 0;
00454 }
00455
00456
00457 char *GlbsToolExpand(char *file)
00458 {
00459
00460
00461
00462
00463 char *fret = 0;
00464
00465 if (file) {
00466
00467 if (file[0] == '/' || (!getenv("HOME"))) {
00468 fret = new char[strlen(file) + 1];
00469 strncpy(fret, file, strlen(file));
00470 } else {
00471 fret = new char[strlen(file) + strlen(getenv("HOME")) + 2];
00472 if (file[0] == '~') {
00473 SPrintf(fret, strlen(file) + strlen(getenv("HOME")) + 2, "%s/%s", getenv("HOME"), file + 1);
00474 } else {
00475 SPrintf(fret, strlen(file) + strlen(getenv("HOME")) + 2, "%s/%s", getenv("HOME"), file);
00476 }
00477 }
00478
00479 }
00480 return fret;
00481 }
00482
00483
00484 int GlbsToolCheckProxy(char **subjname)
00485 {
00486
00487
00488
00489
00490 char pxy[256];
00491 SPrintf(pxy, 256, "/tmp/x509up_u%d", getuid());
00492
00493 if (gDebug > 2)
00494 ErrorInfo("GlbsToolCheckProxy: testing proxy file: %s", pxy);
00495
00496 if (gDebug > 3)
00497 ErrorInfo("GlbsToolCheckProxy: uid:%d euid:%d gid:%d egid:%d",
00498 getuid(), geteuid(), getgid(), getegid());
00499
00500 if (!access(pxy, R_OK)) {
00501
00502 if (setenv("X509_USER_PROXY", pxy, 1))
00503 ErrorInfo("GlbsToolCheckProxy: unable to set X509_USER_PROXY ");
00504
00505 #ifdef R__GLBS22
00506 globus_gsi_cred_handle_t pxycreds = 0;
00507
00508
00509 if (globus_gsi_cred_handle_init(&pxycreds, 0)
00510 != GLOBUS_SUCCESS) {
00511 ErrorInfo("GlbsToolCheckProxy: %s",
00512 "couldn't initialize proxy credential handle");
00513 return 1;
00514 }
00515
00516
00517 if (globus_gsi_cred_read_proxy(pxycreds, pxy)
00518 != GLOBUS_SUCCESS) {
00519 ErrorInfo("GlbsToolCheckProxy: %s %s",
00520 "couldn't read proxy from:", pxy);
00521 globus_gsi_cred_handle_destroy(pxycreds);
00522 return 1;
00523 }
00524
00525
00526 time_t lifetime;
00527 if( globus_gsi_cred_get_lifetime(pxycreds,&lifetime)
00528 != GLOBUS_SUCCESS) {
00529 ErrorInfo("GlbsToolCheckProxy: %s %s",
00530 "couldn't get proxy remaining lifetime");
00531 globus_gsi_cred_handle_destroy(pxycreds);
00532 return 1;
00533 }
00534 globus_gsi_cred_handle_destroy(pxycreds);
00535
00536 if (lifetime > 0) {
00537
00538 if (lifetime < 3600)
00539 ErrorInfo("GlbsToolCheckProxy: WARNING: %s",
00540 "proxy will soon expire (less than %d s)",
00541 lifetime);
00542
00543
00544 X509 *xcert = 0;
00545 FILE *fcert = fopen(pxy, "r");
00546 if (fcert == 0 || !PEM_read_X509(fcert, &xcert, 0, 0)) {
00547 ErrorInfo("GlbsToolCheckProxy: unable to load user proxy certificate ");
00548 return 1;
00549 }
00550 fclose(fcert);
00551 *subjname = X509_NAME_oneline(X509_get_issuer_name(xcert), 0, 0);
00552 if (gDebug > 3)
00553 ErrorInfo("GlbsToolCheckProxy: %s %s",
00554 "Proxy Issuer:", *subjname);
00555
00556 } else {
00557 ErrorInfo("GlbsToolCheckProxy: ERROR: %s",
00558 "proxy are invalid (expired)");
00559 return 1;
00560 }
00561
00562 #else
00563
00564 char * proxy_type;
00565 proxy_cred_desc * pcd = 0;
00566 time_t time_after;
00567 time_t time_now;
00568 time_t time_diff;
00569 ASN1_UTCTIME * asn1_time = 0;
00570
00571
00572 pcd = proxy_cred_desc_new();
00573
00574
00575 pcd->type=CRED_TYPE_PROXY;
00576 if (proxy_load_user_cert(pcd, proxy_file, 0, 0)) {
00577 ErrorInfo("GlbsToolCheckProxy: ERROR: %s (%s)",
00578 "cannot load proxy certificate",proxy_file);
00579 return 1;
00580 }
00581
00582
00583 if ((pcd->upkey = X509_get_pubkey(pcd->ucert)) == 0) {
00584 ErrorInfo("GlbsToolCheckProxy: ERROR: %s",
00585 "cannot get public key");
00586 return 1;
00587 }
00588
00589
00590 asn1_time = ASN1_UTCTIME_new();
00591 X509_gmtime_adj(asn1_time,0);
00592 time_now = ASN1_UTCTIME_mktime(asn1_time);
00593 time_after = ASN1_UTCTIME_mktime(X509_get_notAfter(pcd->ucert));
00594 time_diff = time_after - time_now ;
00595
00596 if (time_diff > 0) {
00597
00598 if (time_diff < 3600)
00599 ErrorInfo("GlbsToolCheckProxy: WARNING: %s",
00600 "proxy will soon expire (less than %d s)",
00601 time_diff);
00602
00603
00604 *subjname = X509_NAME_oneline(X509_get_issuer_name(pcd->ucert), 0, 0);
00605 if (gDebug > 3)
00606 ErrorInfo("GlbsToolCheckProxy: %s %s",
00607 "Proxy Issuer:", *subjname);
00608
00609 } else {
00610 ErrorInfo("GlbsToolCheckProxy: ERROR: %s",
00611 "proxy are invalid (expired)");
00612 return 1;
00613 }
00614
00615 #endif
00616
00617 } else {
00618
00619 ErrorInfo("GlbsToolCheckProxy: Proxy file not existing or"
00620 "not readable");
00621 return 1;
00622 }
00623
00624 return 0;
00625 }
00626
00627 }