static VALUE minidb_close(VALUE self) { DEPOT *db; Data_Get_Struct(self, DEPOT, db); dpclose(db); DATA_PTR(self) = 0; return Qnil; }
/* Close a database handle. */ void gdbm_close(GDBM_FILE dbf){ assert(dbf); if(dbf->depot){ if(dbf->syncmode) dpsync(dbf->depot); dpclose(dbf->depot); } else { if(dbf->syncmode) crsync(dbf->curia); crclose(dbf->curia); } free(dbf); }
/* perform export command */ int doexport(const char *name, int bin){ DEPOT *depot; char *kbuf, *vbuf, *tmp; int err, ksiz, vsiz; /* open a database */ if(!(depot = dpopen(name, DP_OREADER, -1))){ pdperror(name); return 1; } /* initialize the iterator */ dpiterinit(depot); /* loop for each key */ err = FALSE; while((kbuf = dpiternext(depot, &ksiz)) != NULL){ /* retrieve a value with a key */ if(!(vbuf = dpget(depot, kbuf, ksiz, 0, -1, &vsiz))){ pdperror(name); free(kbuf); err = TRUE; break; } /* output data */ if(bin){ tmp = cbbaseencode(kbuf, ksiz); printf("%s\t", tmp); free(tmp); tmp = cbbaseencode(vbuf, vsiz); printf("%s\n", tmp); free(tmp); } else { printf("%s\t%s\n", kbuf, vbuf); } /* free resources */ free(vbuf); free(kbuf); } /* check whether all records were retrieved */ if(dpecode != DP_ENOITEM){ pdperror(name); err = TRUE; } /* close the database */ if(!dpclose(depot)){ pdperror(name); return 1; } return err ? 1 : 0; }
/* perform import command */ int doimport(const char *name, int bnum, int bin){ DEPOT *depot; char *buf, *kbuf, *vbuf, *ktmp, *vtmp; int i, err, ktsiz, vtsiz; /* open a database */ if(!(depot = dpopen(name, DP_OWRITER | DP_OCREAT, bnum))){ pdperror(name); return 1; } /* loop for each line */ err = FALSE; for(i = 1; (buf = getl()) != NULL; i++){ kbuf = buf; if((vbuf = strchr(buf, '\t')) != NULL){ *vbuf = '\0'; vbuf++; /* store a record */ if(bin){ ktmp = cbbasedecode(kbuf, &ktsiz); vtmp = cbbasedecode(vbuf, &vtsiz); if(!dpput(depot, ktmp, ktsiz, vtmp, vtsiz, DP_DOVER)){ pdperror(name); err = TRUE; } free(vtmp); free(ktmp); } else { if(!dpput(depot, kbuf, -1, vbuf, -1, DP_DOVER)){ pdperror(name); err = TRUE; } } } else { fprintf(stderr, "%s: %s: invalid format in line %d\n", progname, name, i); } free(buf); if(err) break; } /* close the database */ if(!dpclose(depot)){ pdperror(name); return 1; } return err ? 1 : 0; }
void DBPrivCloseDB(DBPriv *db) { int ret; if ((ret = pthread_mutex_destroy(&db->lock)) != 0) { errno = ret; Log(LOG_LEVEL_ERR, "Lock is still active during QDBM database handle close. (pthread_mutex_destroy: %s)", GetErrorStr()); } if ((ret = pthread_mutex_destroy(&db->cursor_lock)) != 0) { errno = ret; Log(LOG_LEVEL_ERR, "Cursor lock is still active during QDBM database handle close. (pthread_mutex_destroy: %s)", GetErrorStr()); } if (!dpclose(db->depot)) { Log(LOG_LEVEL_ERR, "Unable to close QDBM database. (dpclose: %s)", dperrmsg(dpecode)); } free(db); }
/* Initialize the root directory. */ int master_init(const char *rootdir){ DEPOT *depot; FILE *ofp; char path[URIBUFSIZ]; int err; assert(rootdir); if(est_mkdir(rootdir) == -1 && errno != EEXIST) return FALSE; err = FALSE; sprintf(path, "%s%c%s", rootdir, ESTPATHCHR, METAFILE); if((depot = dpopen(path, DP_OWRITER | DP_OCREAT | DP_OTRUNC, MINIBNUM))){ if(!dpput(depot, MMKMAGIC, -1, MMKMAGVAL, -1, DP_DKEEP)) err = TRUE; if(!dpclose(depot)) err = TRUE; } else { err = TRUE; } sprintf(path, "%s%c%s", rootdir, ESTPATHCHR, CONFFILE); if((ofp = fopen(path, "wb")) != NULL){ fprintf(ofp, "# binding address of TCP (0.0.0.0 means every address)\n"); fprintf(ofp, "bindaddr: 0.0.0.0\n"); fprintf(ofp, "\n"); fprintf(ofp, "# port number of TCP\n"); fprintf(ofp, "portnum: 1978\n"); fprintf(ofp, "\n"); fprintf(ofp, "# public URL (absolute URL)\n"); fprintf(ofp, "publicurl:\n"); fprintf(ofp, "\n"); fprintf(ofp, "# running mode (1:normal, 2:readonly)\n"); fprintf(ofp, "runmode: 1\n"); fprintf(ofp, "\n"); fprintf(ofp, "# authorization mode (1:none, 2:admin, 3:all)\n"); fprintf(ofp, "authmode: 2\n"); fprintf(ofp, "\n"); fprintf(ofp, "# maximum length of data to receive (in kilobytes)\n"); fprintf(ofp, "recvmax: 1024\n"); fprintf(ofp, "\n"); fprintf(ofp, "# maximum number of connections at the same time\n"); fprintf(ofp, "maxconn: 30\n"); fprintf(ofp, "\n"); fprintf(ofp, "# idle time to start flushing (in seconds)\n"); fprintf(ofp, "idleflush: 20\n"); fprintf(ofp, "\n"); fprintf(ofp, "# idle time to start synchronizing (in seconds)\n"); fprintf(ofp, "idlesync: 300\n"); fprintf(ofp, "\n"); fprintf(ofp, "# timeout of a session (in seconds)\n"); fprintf(ofp, "sessiontimeout: 600\n"); fprintf(ofp, "\n"); fprintf(ofp, "# timeout of search (in seconds)\n"); fprintf(ofp, "searchtimeout: 15\n"); fprintf(ofp, "\n"); fprintf(ofp, "# maximum number of documents to send\n"); fprintf(ofp, "searchmax: 1000\n"); fprintf(ofp, "\n"); fprintf(ofp, "# maximum depth of meta search\n"); fprintf(ofp, "searchdepth: 5\n"); fprintf(ofp, "\n"); fprintf(ofp, "# whether to rate URI for scoring (0:no, 1:yes)\n"); fprintf(ofp, "rateuri: 1\n"); fprintf(ofp, "\n"); fprintf(ofp, "# merge method of meta search (1:score, 2:score and rank, 3:rank)\n"); fprintf(ofp, "mergemethod: 2\n"); fprintf(ofp, "\n"); fprintf(ofp, "# host name of the proxy\n"); fprintf(ofp, "proxyhost:\n"); fprintf(ofp, "\n"); fprintf(ofp, "# port number of the proxy\n"); fprintf(ofp, "proxyport:\n"); fprintf(ofp, "\n"); fprintf(ofp, "# path of the log file (relative path or absolute path)\n"); fprintf(ofp, "logfile: %s\n", LOGFILE); fprintf(ofp, "\n"); fprintf(ofp, "# logging level (1:debug, 2:information, 3:warning, 4:error, 5:none)\n"); fprintf(ofp, "loglevel: 2\n"); fprintf(ofp, "\n"); fprintf(ofp, "# command for backup (absolute path of a command)\n"); fprintf(ofp, "backupcmd:\n"); fprintf(ofp, "\n"); fprintf(ofp, "# scale prediction (1:small, 2:medium, 3:large, 4:huge)\n"); fprintf(ofp, "scalepred: 2\n"); fprintf(ofp, "\n"); fprintf(ofp, "# score expression (1:void, 2:char, 3:int, 4:asis)\n"); fprintf(ofp, "scoreexpr: 2\n"); fprintf(ofp, "\n"); fprintf(ofp, "# attribute indexes (attribute name and data type)\n"); fprintf(ofp, "attrindex: @mdate{{!}}seq\n"); fprintf(ofp, "attrindex: @title{{!}}str\n"); fprintf(ofp, "\n"); fprintf(ofp, "# document root directory (absolute path of a directory to be public)\n"); fprintf(ofp, "docroot:\n"); fprintf(ofp, "\n"); fprintf(ofp, "# index file (name of directory index files)\n"); fprintf(ofp, "indexfile:\n"); fprintf(ofp, "\n"); fprintf(ofp, "# decimal IP addresses of trusted nodes\n"); fprintf(ofp, "trustednode:\n"); fprintf(ofp, "\n"); fprintf(ofp, "# whether to deny all nodes except for trusted nodes (0:no, 1:yes)\n"); fprintf(ofp, "denyuntrusted: 0\n"); fprintf(ofp, "\n"); fprintf(ofp, "# maximum size of the index cache (in megabytes)\n"); fprintf(ofp, "cachesize: 64\n"); fprintf(ofp, "\n"); fprintf(ofp, "# maximum number of cached records for document attributes\n"); fprintf(ofp, "cacheanum: 8192\n"); fprintf(ofp, "\n"); fprintf(ofp, "# maximum number of cached records for document texts\n"); fprintf(ofp, "cachetnum: 1024\n"); fprintf(ofp, "\n"); fprintf(ofp, "# maximum number of cached records for occurrence results\n"); fprintf(ofp, "cachernum: 256\n"); fprintf(ofp, "\n"); fprintf(ofp, "# name of the attribute of the special cache\n"); fprintf(ofp, "specialcache:\n"); fprintf(ofp, "\n"); fprintf(ofp, "# lower limit of cache usage to use the helper\n"); fprintf(ofp, "helpershift: 0.9\n"); fprintf(ofp, "\n"); fprintf(ofp, "# maximum number of expansion of wild cards\n"); fprintf(ofp, "wildmax: 256\n"); fprintf(ofp, "\n"); fprintf(ofp, "# text size limitation of indexing documents (in kilobytes)\n"); fprintf(ofp, "limittextsize: 128\n"); fprintf(ofp, "\n"); fprintf(ofp, "# whole width of the snippet of each shown document\n"); fprintf(ofp, "snipwwidth: 480\n"); fprintf(ofp, "\n"); fprintf(ofp, "# width of strings picked up from the beginning of the text\n"); fprintf(ofp, "sniphwidth: 96\n"); fprintf(ofp, "\n"); fprintf(ofp, "# width of strings picked up around each highlighted word\n"); fprintf(ofp, "snipawidth: 96\n"); fprintf(ofp, "\n"); fprintf(ofp, "# whether to check documents by scanning (0:no, 1:yes)\n"); fprintf(ofp, "scancheck: 1\n"); fprintf(ofp, "\n"); fprintf(ofp, "# number of keywords for similarity search (0 means disabled)\n"); fprintf(ofp, "smlrvnum: 32\n"); fprintf(ofp, "\n"); fprintf(ofp, "# number of documents for delay of keyword extraction\n"); fprintf(ofp, "extdelay: 4096\n"); fprintf(ofp, "\n"); fprintf(ofp, "# e-mail address of the administrator\n"); fprintf(ofp, "adminemail: [email protected]\n"); fprintf(ofp, "\n"); fprintf(ofp, "# expressions to replace the URI of each document\n"); fprintf(ofp, "uireplace: ^file:///home/mikio/public_html/{{!}}http://localhost/\n"); fprintf(ofp, "uireplace: /index\\.html?${{!}}/\n"); fprintf(ofp, "\n"); fprintf(ofp, "# extra attributes to be shown\n"); fprintf(ofp, "uiextattr: @author|Author\n"); fprintf(ofp, "uiextattr: @mdate|Modification Date\n"); fprintf(ofp, "\n"); fprintf(ofp, "# mode of phrase form" " (1:usual, 2:simplified, 3:rough, 4:union: 5:intersection)\n"); fprintf(ofp, "uiphraseform: 2\n"); fprintf(ofp, "\n"); fprintf(ofp, "# tuning parameters for similarity search\n"); fprintf(ofp, "uismlrtune: 16 1024 4096\n"); fprintf(ofp, "\n"); if(fclose(ofp) == EOF) err = TRUE; } else { err = TRUE; } sprintf(path, "%s%c%s", rootdir, ESTPATHCHR, PIDFILE); unlink(path); sprintf(path, "%s%c%s", rootdir, ESTPATHCHR, STOPFILE); unlink(path); sprintf(path, "%s%c%s", rootdir, ESTPATHCHR, USERFILE); if((ofp = fopen(path, "wb")) != NULL){ if(fclose(ofp) == EOF) err = TRUE; } else { err = TRUE; } sprintf(path, "%s%c%s", rootdir, ESTPATHCHR, LOGFILE); if((ofp = fopen(path, "wb")) != NULL){ if(fclose(ofp) == EOF) err = TRUE; } else { err = TRUE; } sprintf(path, "%s%c%s", rootdir, ESTPATHCHR, NODEDIR); est_rmdir_rec(path); if(est_mkdir(path) == -1) err = TRUE; sprintf(path, "%s%c%s", rootdir, ESTPATHCHR, SESSDIR); est_rmdir_rec(path); if(est_mkdir(path) == -1) err = TRUE; return err ? FALSE : TRUE; }
/* Get a database handle after the fashion of GDBM. */ GDBM_FILE gdbm_open(char *name, int block_size, int read_write, int mode, void (*fatal_func)()){ GDBM_FILE dbf; int dpomode; DEPOT *depot; int flags, fd; assert(name); dpomode = DP_OREADER; flags = O_RDONLY; if(read_write & GDBM_READER){ dpomode = GDBM_READER; if(read_write & GDBM_NOLOCK) dpomode |= DP_ONOLCK; if(read_write & GDBM_LOCKNB) dpomode |= DP_OLCKNB; flags = O_RDONLY; } else if(read_write & GDBM_WRITER){ dpomode = DP_OWRITER; if(read_write & GDBM_NOLOCK) dpomode |= DP_ONOLCK; if(read_write & GDBM_LOCKNB) dpomode |= DP_OLCKNB; flags = O_RDWR; } else if(read_write & GDBM_WRCREAT){ dpomode = DP_OWRITER | DP_OCREAT; if(read_write & GDBM_NOLOCK) dpomode |= DP_ONOLCK; if(read_write & GDBM_LOCKNB) dpomode |= DP_OLCKNB; if(read_write & GDBM_SPARSE) dpomode |= DP_OSPARSE; flags = O_RDWR | O_CREAT; } else if(read_write & GDBM_NEWDB){ dpomode = DP_OWRITER | DP_OCREAT | DP_OTRUNC; if(read_write & GDBM_NOLOCK) dpomode |= DP_ONOLCK; if(read_write & GDBM_LOCKNB) dpomode |= DP_OLCKNB; if(read_write & GDBM_SPARSE) dpomode |= DP_OSPARSE; flags = O_RDWR | O_CREAT | O_TRUNC; } else { gdbm_errno = GDBM_ILLEGAL_DATA; return NULL; } mode |= 00600; if((fd = open(name, flags, mode)) == -1 || close(fd) == -1){ gdbm_errno = GDBM_FILE_OPEN_ERROR; return NULL; } if(!(depot = dpopen(name, dpomode, HV_INITBNUM))){ gdbm_errno = gdbm_geterrno(dpecode); if(dpecode == DP_ESTAT) gdbm_errno = GDBM_FILE_OPEN_ERROR; return NULL; } if(dpomode & DP_OWRITER){ if(!dpsetalign(depot, HV_ALIGNSIZ)){ gdbm_errno = gdbm_geterrno(dpecode); dpclose(depot); } } if((dpomode & DP_OWRITER) && (read_write & GDBM_SYNC)){ if(!dpsync(depot)){ gdbm_errno = gdbm_geterrno(dpecode); dpclose(depot); } } if(!(dbf = malloc(sizeof(GDBM)))){ gdbm_errno = GDBM_MALLOC_ERROR; dpclose(depot); return NULL; } dbf->depot = depot; dbf->curia = NULL; dbf->syncmode = (dpomode & DP_OWRITER) && (read_write & GDBM_SYNC) ? TRUE : FALSE; return dbf; }
/* Get a database handle after the fashion of QDBM. */ GDBM_FILE gdbm_open2(char *name, int read_write, int mode, int bnum, int dnum, int align){ GDBM_FILE dbf; int dpomode, cromode, flags, fd; struct stat sbuf; DEPOT *depot; CURIA *curia; assert(name); dpomode = DP_OREADER; cromode = CR_OREADER; flags = O_RDONLY; if(read_write & GDBM_READER){ dpomode = DP_OREADER; cromode = CR_OREADER; if(read_write & GDBM_NOLOCK){ dpomode |= DP_ONOLCK; cromode |= CR_ONOLCK; } if(read_write & GDBM_LOCKNB){ dpomode |= DP_OLCKNB; cromode |= CR_OLCKNB; } flags = O_RDONLY; } else if(read_write & GDBM_WRITER){ dpomode = DP_OWRITER; cromode = CR_OWRITER; if(read_write & GDBM_NOLOCK){ dpomode |= DP_ONOLCK; cromode |= CR_ONOLCK; } if(read_write & GDBM_LOCKNB){ dpomode |= DP_OLCKNB; cromode |= CR_OLCKNB; } flags = O_RDWR; } else if(read_write & GDBM_WRCREAT){ dpomode = DP_OWRITER | DP_OCREAT; cromode = CR_OWRITER | CR_OCREAT; if(read_write & GDBM_NOLOCK){ dpomode |= DP_ONOLCK; cromode |= CR_ONOLCK; } if(read_write & GDBM_LOCKNB){ dpomode |= DP_OLCKNB; cromode |= CR_OLCKNB; } if(read_write & GDBM_SPARSE){ dpomode |= DP_OSPARSE; cromode |= CR_OSPARSE; } flags = O_RDWR | O_CREAT; } else if(read_write & GDBM_NEWDB){ dpomode = DP_OWRITER | DP_OCREAT | DP_OTRUNC; cromode = CR_OWRITER | CR_OCREAT | CR_OTRUNC; if(read_write & GDBM_NOLOCK){ dpomode |= DP_ONOLCK; cromode |= CR_ONOLCK; } if(read_write & GDBM_LOCKNB){ dpomode |= DP_OLCKNB; cromode |= CR_OLCKNB; } if(read_write & GDBM_SPARSE){ dpomode |= DP_OSPARSE; cromode |= CR_OSPARSE; } flags = O_RDWR | O_CREAT | O_TRUNC; } else { gdbm_errno = GDBM_ILLEGAL_DATA; return NULL; } if(lstat(name, &sbuf) != -1){ if(S_ISDIR(sbuf.st_mode)){ if(dnum < 1) dnum = 1; } else { dnum = 0; } } depot = NULL; curia = NULL; if(dnum > 0){ mode |= 00700; if((cromode & CR_OCREAT)){ if(mkdir(name, mode) == -1 && errno != EEXIST){ gdbm_errno = GDBM_FILE_OPEN_ERROR; return NULL; } } if(!(curia = cropen(name, cromode, bnum, dnum))){ gdbm_errno = gdbm_geterrno(dpecode); return NULL; } if(cromode & CR_OWRITER) crsetalign(curia, align); if((cromode & CR_OWRITER) && (read_write & GDBM_SYNC)) crsync(curia); } else { mode |= 00600; if(dpomode & DP_OWRITER){ if((fd = open(name, flags, mode)) == -1 || close(fd) == -1){ gdbm_errno = GDBM_FILE_OPEN_ERROR; return NULL; } } if(!(depot = dpopen(name, dpomode, bnum))){ gdbm_errno = gdbm_geterrno(dpecode); return NULL; } if(dpomode & DP_OWRITER) dpsetalign(depot, align); if((dpomode & DP_OWRITER) && (read_write & GDBM_SYNC)) dpsync(depot); } if(!(dbf = malloc(sizeof(GDBM)))){ gdbm_errno = GDBM_MALLOC_ERROR; if(depot) dpclose(depot); if(curia) crclose(curia); return NULL; } dbf->depot = depot; dbf->curia = curia; dbf->syncmode = (dpomode & DP_OWRITER) && (read_write & GDBM_SYNC) ? TRUE : FALSE; return dbf; }
int main(int argc, char *argv[]) { DEPOT *dbmap = NULL; char *str_prefix = "dbbm_key_prefix_"; char *key, keystr[24]; unsigned long i; int rc = 0; PDUMMY_DATA datap; if (argc < 3) { fprintf(stderr, "Usage : <prog> <dbpath> <datasize>\n"); exit(1); } dbmap = dpopen(argv[1], DP_OWRITER|DP_OCREAT|DP_OSPARSE|DP_ONOLCK, -1); if (!dbmap) { fprintf(stderr, "Unable to open the dbbm file \n"); exit(1); } datap = (PDUMMY_DATA) malloc(sizeof(DUMMY_DATA)); if (!datap) { fprintf(stderr, "Malloc error %s\n", strerror(errno)); exit(1); } unsigned long datasize = strtoul(argv[2], NULL, 10); // push data for (i = 0; i < datasize; i++) { asprintf(keystr, "%s%lu", str_prefix, i); datap->x = i; datap->y = i+1; datap->z = i+2; if (!dpput(dbmap, keystr, strlen(keystr), (char *) datap, sizeof(DUMMY_DATA), DP_DOVER)) { fprintf(stderr, "Unable to insert to qdbm\n"); }; } if(!dpclose(dbmap)){ fprintf(stderr, "dpclose: %s\n", dperrmsg(dpecode)); return 1; } //read data dbmap = dpopen(argv[1], DP_OREADER, -1); if (!dbmap) { fprintf(stderr, "Unable to open the dbbm file \n"); exit(1); } fprintf(stdout, "Starting read of the database sequentially\n"); if(!dpiterinit(dbmap)){ fprintf(stderr, "dpiterinit: %s\n", dperrmsg(dpecode)); } /* scan with the iterator */ while ((key = dpiternext(dbmap, NULL)) != NULL) { if (!(datap = (PDUMMY_DATA) dpget(dbmap, key, -1, 0, sizeof(DUMMY_DATA), NULL))) { fprintf(stderr, "Value is not found for key %s\n", key); fprintf(stderr, "dpget: %s\n", dperrmsg(dpecode)); free(key); break; } /* fprintf(stdout, "Data read for dbm : x=%lu y=%lu z=%lu\n", datap->x, datap->y, datap->z);*/ free(datap); } fprintf(stdout, "End of the database reached\n"); if(!dpclose(dbmap)){ fprintf(stderr, "dpclose: %s\n", dperrmsg(dpecode)); return 1; } return 0; }
static int auth_ticket_assert(struct link *link, time_t stoptime) { /* FIXME need to save errno ? */ char line[AUTH_LINE_MAX]; char **tickets = client_tickets; if(tickets) { char *ticket; char digest[DIGEST_LENGTH]; for (ticket = *tickets; ticket; ticket = *(++tickets)) { if (access(ticket, R_OK) == -1) { debug(D_AUTH, "could not access ticket %s: %s", ticket, strerror(errno)); continue; } /* load the digest */ /* WARNING: openssl is *very* bad at giving sensible output. Use the last * 32 non-space characters as the MD5 sum. */ char command[PATH_MAX * 2 + 4096]; sprintf(command, "openssl rsa -in '%s' -pubout 2> /dev/null | openssl md5 2> /dev/null | tr -d '[:space:]' | tail -c 32", ticket); FILE *digestf = popen(command, "r"); if(full_fread(digestf, digest, DIGEST_LENGTH) < DIGEST_LENGTH) { pclose(digestf); return 0; } pclose(digestf); debug(D_AUTH, "trying ticket %.*s", DIGEST_LENGTH, digest); if(link_putlstring(link, digest, DIGEST_LENGTH, stoptime) <= 0) return 0; if(link_putliteral(link, "\n", stoptime) <= 0) return 0; if(link_readline(link, line, sizeof(line), stoptime) <= 0) return 0; if(strcmp(line, "declined") == 0) continue; unsigned long length = strtoul(line, NULL, 10); if(errno == ERANGE || errno == EINVAL) return 0; /* not a number? */ debug(D_AUTH, "receiving challenge of %d bytes", length); FILE *in, *out; static const char command_template[] = "T1=`mktemp`\n" /* signed challenge */ "T2=`mktemp`\n" /* private key without comments */ "sed '/^\\s*#/d' < '%s' > \"$T2\"\n" "openssl rsautl -inkey \"$T2\" -sign > \"$T1\" 2> /dev/null\n" "R=\"$?\"\n" "if [ \"$R\" -ne 0 ]; then\n" " rm -f \"$T1\" \"$T2\"\n" " exit \"$R\"\n" "fi\n" "ls -l \"$T1\" | awk '{ print $5 }'\n" "cat \"$T1\"\n" "rm -f \"$T1\" \"$T2\"\n"; sprintf(command, command_template, ticket); pid_t pid = dpopen(command, &in, &out); if(pid == 0) return 0; if(link_stream_to_file(link, in, length, stoptime) <= 0) { dpclose(in, out, pid); debug(D_AUTH, "openssl failed, your keysize may be too small"); debug(D_AUTH, "please debug using \"dd if=/dev/urandom count=64 bs=1 | openssl rsautl -inkey <ticket file> -sign\""); return 0; } fclose(in); in = NULL; if(link_stream_from_file(link, out, 1 << 20, stoptime) <= 0) { dpclose(in, out, pid); debug(D_AUTH, "openssl failed, your keysize may be too small"); debug(D_AUTH, "please debug using \"dd if=/dev/urandom count=64 bs=1 | openssl rsautl -inkey <ticket file> -sign\""); return 0; } dpclose(in, out, pid); if(link_readline(link, line, sizeof(line), stoptime) <= 0) return 0; if(strcmp(line, "success") == 0) { debug(D_AUTH, "succeeded challenge for %.*s\n", DIGEST_LENGTH, digest); return 1; } else if(strcmp(line, "failure") == 0) { debug(D_AUTH, "failed challenge for %.*s\n", DIGEST_LENGTH, digest); errno = EINVAL; return 0; } else { debug(D_AUTH, "received bad response: '%s'", line); errno = EINVAL; return 0; } } } link_putliteral(link, "==\n", stoptime); return 0; }
static int auth_ticket_accept(struct link *link, char **subject, time_t stoptime) { int serrno = errno; int status = 0; char line[AUTH_LINE_MAX]; char ticket_subject[AUTH_LINE_MAX]; char *ticket = NULL; errno = 0; debug(D_AUTH, "ticket: waiting for tickets"); while(1) { if(link_readline(link, line, sizeof(line), stoptime) > 0) { if(strcmp(line, "==") == 0) { debug(D_AUTH, "ticket: exhausted all ticket challenges"); break; } else if(strlen(line) == DIGEST_LENGTH) { char ticket_digest[DIGEST_LENGTH + 1]; strcpy(ticket_digest, line); strcpy(ticket_subject, line); debug(D_AUTH, "ticket: read ticket digest: %s", ticket_digest); if(server_callback) { free(ticket); /* free previously allocated ticket string or NULL (noop) */ ticket = server_callback(ticket_digest); if(ticket) { static const char command_template[] = "T1=`mktemp`\n" /* The RSA Public Key */ "T2=`mktemp`\n" /* The Challenge */ "T3=`mktemp`\n" /* The Signed Challenge */ "T4=`mktemp`\n" /* The Decrypted (verified) Signed Challenge */ "echo -n '%s' > \"$T1\"\n" "dd if=/dev/urandom of=\"$T2\" bs=%u count=1 > /dev/null 2> /dev/null\n" "cat \"$T2\"\n" /* to stdout */ "cat > \"$T3\"\n" /* from stdin */ "openssl rsautl -inkey \"$T1\" -pubin -verify < \"$T3\" > \"$T4\" 2> /dev/null\n" "cmp \"$T2\" \"$T4\" > /dev/null 2> /dev/null\n" "R=\"$?\"\n" "rm -f \"$T1\" \"$T2\" \"$T3\" \"$T4\" > /dev/null 2> /dev/null\n" "exit \"$R\"\n"; char *command = xxmalloc(sizeof(command_template) + strlen(ticket) + 64); sprintf(command, command_template, ticket, CHALLENGE_LENGTH); FILE *in, *out; pid_t pid = dpopen(command, &in, &out); free(command); if(pid == 0) break; if(!link_putfstring(link, "%zu\n", stoptime, CHALLENGE_LENGTH)) break; if(!link_stream_from_file(link, out, CHALLENGE_LENGTH, stoptime)) break; if(link_readline(link, line, sizeof(line), stoptime) <= 0) break; unsigned long length = strtoul(line, NULL, 10); if(errno == ERANGE || errno == EINVAL) break; /* not a number? */ if(!link_stream_to_file(link, in, length, stoptime)) break; int result = dpclose(in, out, pid); if(result == 0) { debug(D_AUTH, "succeeded challenge for %s\n", ticket_digest); link_putliteral(link, "success\n", stoptime); status = 1; break; } else { debug(D_AUTH, "failed challenge for %s\n", ticket_digest); link_putliteral(link, "failure\n", stoptime); break; } } else { debug(D_AUTH, "declining key %s", ticket_digest); link_putliteral(link, "declined\n", stoptime); } } else { debug(D_AUTH, "declining key %s", ticket_digest); link_putliteral(link, "declined\n", stoptime); } } else { debug(D_AUTH, "ticket: bad response"); break; } } else { break; } } if(status) { *subject = xxmalloc(AUTH_LINE_MAX); strcpy(*subject, ticket_subject); } free(ticket); /* free previously allocated ticket string or NULL (noop) */ errno = serrno; return status; }
static void minidb_free(DEPOT *db) { if (db) { dpclose(db); } }