int main( int argc, char **argv) { int c, i, done = 0; char *input; char **v; pushfile(stdin); init(argc, argv); for (i = 0; !done && i < ncmdline; i++) { v = breakline(cmdline[i], &c); if (c) done = command(c, v); xfree(v); } if (cmdline) { xfree(cmdline); return exitcode; } while (!done) { if ((input = fetchline()) == NULL) break; v = breakline(input, &c); if (c) done = command(c, v); doneline(input, v); } return exitcode; }
void command_loop(void) { int c, i, j = 0, done = 0; char *input; char **v; const cmdinfo_t *ct; for (i = 0; !done && i < ncmdline; i++) { input = strdup(cmdline[i]); if (!input) { fprintf(stderr, _("cannot strdup command '%s': %s\n"), cmdline[i], strerror(errno)); exit(1); } v = breakline(input, &c); if (c) { ct = find_command(v[0]); if (ct) { if (ct->flags & CMD_FLAG_GLOBAL) done = command(ct, c, v); else { j = 0; while (!done && (j = args_command(j))) done = command(ct, c, v); } } else fprintf(stderr, _("command \"%s\" not found\n"), v[0]); } doneline(input, v); } if (cmdline) { free(cmdline); return; } while (!done) { if ((input = fetchline()) == NULL) break; v = breakline(input, &c); if (c) { ct = find_command(v[0]); if (ct) done = command(ct, c, v); else fprintf(stderr, _("command \"%s\" not found\n"), v[0]); } doneline(input, v); } }
main() { int len; // extern int max; // extern char longest[]; max=0; while((len=fetchline()) > 1) if (len>max) { max=len; copy(); } printf("%s",longest); return 0; }
main() /* find longest line */ { int len; /* current line length */ int max; /* max length so far */ char line[MAXLINE]; /* current input line */ char save[MAXLINE]; /* longest line saved */ max = 0; while ((len = fetchline(line, MAXLINE)) > 0) if (len > max) { max = len; copy(line, save); } if ((max == (MAXLINE - 1)) && (line[MAXLINE - 1] == '\0')) printf("max input line size exceeded\n"); else if (max > 0) /* there was a line */ printf("%s", save); }
static void command_loop(void) { int i, done = 0, fetchable = 0, prompted = 0; char *input; for (i = 0; !done && i < ncmdline; i++) { done = qemuio_command(qemuio_bs, cmdline[i]); } if (cmdline) { g_free(cmdline); return; } while (!done) { if (!prompted) { printf("%s", get_prompt()); fflush(stdout); qemu_set_fd_handler(STDIN_FILENO, prep_fetchline, NULL, &fetchable); prompted = 1; } main_loop_wait(false); if (!fetchable) { continue; } input = fetchline(); if (input == NULL) { break; } done = qemuio_command(qemuio_bs, input); g_free(input); prompted = 0; fetchable = 0; } qemu_set_fd_handler(STDIN_FILENO, NULL, NULL, NULL); }
/* Converts a PEM encoded file into its binary form * * RFC 1421 Privacy Enhancement for Electronic Mail, February 1993 * RFC 934 Message Encapsulation, January 1985 */ err_t pem_to_bin(chunk_t *blob, chunk_t *passphrase, bool *pgp) { typedef enum { PEM_PRE = 0, PEM_MSG = 1, PEM_HEADER = 2, PEM_BODY = 3, PEM_POST = 4, PEM_ABORT = 5 } state_t; encryption_algorithm_t alg = ENCR_UNDEFINED; size_t key_size = 0; bool encrypted = FALSE; state_t state = PEM_PRE; chunk_t src = *blob; chunk_t dst = *blob; chunk_t line = CHUNK_INITIALIZER; chunk_t iv = CHUNK_INITIALIZER; u_char iv_buf[16]; /* MD5 digest size */ /* zero size of converted blob */ dst.len = 0; /* zero size of IV */ iv.ptr = iv_buf; iv.len = 0; pem_init_logger(); while (fetchline(&src, &line)) { if (state == PEM_PRE) { if (find_boundary("BEGIN", &line)) { state = PEM_MSG; } continue; } else { if (find_boundary("END", &line)) { state = PEM_POST; break; } if (state == PEM_MSG) { state = (memchr(line.ptr, ':', line.len) == NULL) ? PEM_BODY : PEM_HEADER; } if (state == PEM_HEADER) { err_t ugh = NULL; chunk_t name = CHUNK_INITIALIZER; chunk_t value = CHUNK_INITIALIZER; /* an empty line separates HEADER and BODY */ if (line.len == 0) { state = PEM_BODY; continue; } /* we are looking for a parameter: value pair */ logger->log(logger, CONTROL|LEVEL2, " %.*s", (int)line.len, line.ptr); ugh = extract_parameter_value(&name, &value, &line); if (ugh != NULL) continue; if (match("Proc-Type", &name) && *value.ptr == '4') encrypted = TRUE; else if (match("DEK-Info", &name)) { size_t len = 0; chunk_t dek; if (!extract_token(&dek, ',', &value)) dek = value; /* we support DES-EDE3-CBC encrypted files, only */ if (match("DES-EDE3-CBC", &dek)) { alg = ENCR_3DES; key_size = 24; } else if (match("AES-128-CBC", &dek)) { alg = ENCR_AES_CBC; key_size = 16; } else if (match("AES-192-CBC", &dek)) { alg = ENCR_AES_CBC; key_size = 24; } else if (match("AES-256-CBC", &dek)) { alg = ENCR_AES_CBC; key_size = 32; } else { return "encryption algorithm not supported"; } eat_whitespace(&value); ugh = ttodata(value.ptr, value.len, 16, iv.ptr, 16, &len); if (ugh) return "error in IV"; iv.len = len; } } else /* state is PEM_BODY */ { const char *ugh = NULL; size_t len = 0; chunk_t data; /* remove any trailing whitespace */ if (!extract_token(&data ,' ', &line)) { data = line; } /* check for PGP armor checksum */ if (*data.ptr == '=') { *pgp = TRUE; data.ptr++; data.len--; logger->log(logger, CONTROL|LEVEL2, " Armor checksum: %.*s", (int)data.len, data.ptr); continue; } ugh = ttodata(data.ptr, data.len, 64, dst.ptr, blob->len - dst.len, &len); if (ugh) { state = PEM_ABORT; break; } else { dst.ptr += len; dst.len += len; } } } } /* set length to size of binary blob */ blob->len = dst.len; if (state != PEM_POST) return "file coded in unknown format, discarded"; return (encrypted)? pem_decrypt(blob, alg, key_size, &iv, passphrase) : NULL; }
void vi() { REG int key; /* keystroke from user */ long count; /* numeric argument to some functions */ REG struct keystru *keyptr;/* pointer to vikeys[] element */ MARK tcurs; /* temporary cursor */ int prevkey;/* previous key, if d/c/y/</>/! */ MARK range; /* start of range for d/c/y/</>/! */ char text[132]; int dotkey; /* last "key" of a change */ int dotpkey;/* last "prevkey" of a change */ int dotkey2;/* last extra "getkey()" of a change */ int dotcnt; /* last "count" of a change */ int firstkey; REG int i; /* tell the redraw() function to start from scratch */ redraw(MARK_UNSET, FALSE); #ifdef lint /* lint says that "range" might be used before it is set. This * can't really happen due to the way "range" and "prevkey" are used, * but lint doesn't know that. This line is here ONLY to keep lint * happy. */ range = 0L; #endif /* safeguard against '.' with no previous command */ dotkey = dotpkey = dotkey2 = dotcnt = 0; /* go immediately into insert mode, if ":set inputmode" */ firstkey = 0; #ifndef NO_EXTENSIONS if (*o_inputmode) { firstkey = 'i'; } #endif /* Repeatedly handle VI commands */ for (count = 0, prevkey = '\0'; mode == MODE_VI; ) { /* if we've moved off the undoable line, then we can't undo it at all */ if (markline(cursor) != U_line) { U_line = 0L; } /* report any changes from the previous command */ if (rptlines >= *o_report) { redraw(cursor, FALSE); msg("%ld line%s %s", rptlines, (rptlines==1?"":"s"), rptlabel); } rptlines = 0L; /* get the next command key. It must be ASCII */ if (firstkey) { key = firstkey; firstkey = 0; } else { do { key = getkey(WHEN_VICMD); } while (key < 0 || key > 127); } #ifdef DEBUG2 debout("\nkey='%c'\n", key); #endif /* Convert a doubled-up operator such as "dd" into "d_" */ if (prevkey && key == prevkey) { key = '_'; } /* look up the structure describing this command */ keyptr = &vikeys[key]; /* '&' and uppercase operators always act like doubled */ if (!prevkey && keyptr->args == CURSOR_MOVED && (key == '&' || isupper(key))) { range = cursor; prevkey = key; key = '_'; keyptr = &vikeys[key]; } #ifndef NO_VISIBLE /* if we're in the middle of a v/V command, reject commands * that aren't operators or movement commands */ if (V_from && !(keyptr->flags & VIZ)) { beep(); prevkey = 0; count = 0; continue; } #endif /* if we're in the middle of a d/c/y/</>/! command, reject * anything but movement. */ if (prevkey && !(keyptr->flags & (MVMT|PTMV))) { beep(); prevkey = 0; count = 0; continue; } /* set the "dot" variables, if we're supposed to */ if (((keyptr->flags & SDOT) || (prevkey && vikeys[prevkey].flags & SDOT)) #ifndef NO_VISIBLE && !V_from #endif ) { dotkey = key; dotpkey = prevkey; dotkey2 = '\0'; dotcnt = count; /* remember the line before any changes are made */ if (U_line != markline(cursor)) { U_line = markline(cursor); strcpy(U_text, fetchline(U_line)); } } /* if this is "." then set other vars from the "dot" vars */ if (key == '.') { key = dotkey; keyptr = &vikeys[key]; prevkey = dotpkey; if (prevkey) { range = cursor; } if (count == 0) { count = dotcnt; } doingdot = TRUE; /* remember the line before any changes are made */ if (U_line != markline(cursor)) { U_line = markline(cursor); strcpy(U_text, fetchline(U_line)); } } else { doingdot = FALSE; } /* process the key as a command */ tcurs = cursor; force_flags = NO_FLAGS; switch (keyptr->args & ARGSMASK) { case ZERO: if (count == 0) { tcurs = cursor & ~(BLKSIZE - 1); break; } /* else fall through & treat like other digits... */ case DIGIT: count = count * 10 + key - '0'; break; case KEYWORD: /* if not on a keyword, fail */ pfetch(markline(cursor)); key = markidx(cursor); if (!isalnum(ptext[key])) { tcurs = MARK_UNSET; break; } /* find the start of the keyword */ while (key > 0 && isalnum(ptext[key - 1])) { key--; } tcurs = (cursor & ~(BLKSIZE - 1)) + key; /* copy it into a buffer, and NUL-terminate it */ i = 0; do { text[i++] = ptext[key++]; } while (isalnum(ptext[key])); text[i] = '\0'; /* call the function */ tcurs = (*keyptr->func)(text, tcurs, count); count = 0L; break; case NO_ARGS: if (keyptr->func) { (*keyptr->func)(); } else { beep(); } count = 0L; break; case CURSOR: tcurs = (*keyptr->func)(cursor, count, key, prevkey); count = 0L; break; case CURSOR_CNT_KEY: if (doingdot) { tcurs = (*keyptr->func)(cursor, count, dotkey2); } else { /* get a key */ i = getkey(KEYMODE(keyptr->args)); if (i == '\033') /* ESC */ { count = 0; tcurs = MARK_UNSET; break; /* exit from "case CURSOR_CNT_KEY" */ } else if (i == ctrl('V')) { i = getkey(0); } /* if part of an SDOT command, remember it */ if (keyptr->flags & SDOT || (prevkey && vikeys[prevkey].flags & SDOT)) { dotkey2 = i; } /* do it */ tcurs = (*keyptr->func)(cursor, count, i); } count = 0L; break; case CURSOR_MOVED: #ifndef NO_VISIBLE if (V_from) { range = cursor; tcurs = V_from; count = 0L; prevkey = key; key = (V_linemd ? 'V' : 'v'); keyptr = &vikeys[key]; } else #endif { prevkey = key; range = cursor; force_flags = LNMD|INCL; } break; case CURSOR_EOL: prevkey = key; /* a zero-length line needs special treatment */ pfetch(markline(cursor)); if (plen == 0) { /* act on a zero-length section of text */ range = tcurs = cursor; key = '0'; } else { /* act like CURSOR_MOVED with '$' movement */ range = cursor; tcurs = m_rear(cursor, 1L); key = '$'; } count = 0L; keyptr = &vikeys[key]; break; case CURSOR_TEXT: do { text[0] = key; text[1] = '\0'; if (doingdot || vgets(key, text + 1, sizeof text - 1) >= 0) { /* reassure user that <CR> was hit */ qaddch('\r'); refresh(); /* call the function with the text */ tcurs = (*keyptr->func)(cursor, text); } else { if (exwrote || mode == MODE_COLON) { redraw(MARK_UNSET, FALSE); } mode = MODE_VI; } } while (mode == MODE_COLON); count = 0L; break; } /* if that command took us out of vi mode, then exit the loop * NOW, without tweaking the cursor or anything. This is very * important when mode == MODE_QUIT. */ if (mode != MODE_VI) { break; } /* now move the cursor, as appropriate */ if (prevkey && ((keyptr->flags & MVMT) #ifndef NO_VISIBLE || V_from #endif ) && count == 0L) { /* movements used as targets are less strict */ tcurs = adjmove(cursor, tcurs, (int)(keyptr->flags | force_flags)); } else if (keyptr->args == CURSOR_MOVED) { /* the < and > keys have FRNT, * but it shouldn't be applied yet */ tcurs = adjmove(cursor, tcurs, FINL); } else { tcurs = adjmove(cursor, tcurs, (int)(keyptr->flags | force_flags | FINL)); } /* was that the end of a d/c/y/</>/! command? */ if (prevkey && ((keyptr->flags & MVMT) #ifndef NO_VISIBLE || V_from #endif ) && count == 0L) { #ifndef NO_VISIBLE /* turn off the hilight */ V_from = 0L; #endif /* if the movement command failed, cancel operation */ if (tcurs == MARK_UNSET) { prevkey = 0; count = 0; continue; } /* make sure range=front and tcurs=rear. Either way, * leave cursor=range since that's where we started. */ cursor = range; if (tcurs < range) { range = tcurs; tcurs = cursor; } /* The 'w' and 'W' destinations should never take us * to the front of a line. Instead, they should take * us only to the end of the preceding line. */ if ((keyptr->flags & NWRP) == NWRP && markline(range) < markline(tcurs) && (markline(tcurs) > nlines || tcurs == m_front(tcurs, 0L))) { tcurs = (tcurs & ~(BLKSIZE - 1)) - BLKSIZE; pfetch(markline(tcurs)); tcurs += plen; } /* adjust for line mode & inclusion of last char/line */ i = (keyptr->flags | vikeys[prevkey].flags); switch ((i | force_flags) & (INCL|LNMD)) { case INCL: tcurs++; break; case INCL|LNMD: tcurs += BLKSIZE; /* fall through... */ case LNMD: range &= ~(BLKSIZE - 1); tcurs &= ~(BLKSIZE - 1); break; } /* run the function */ tcurs = (*vikeys[prevkey].func)(range, tcurs); if (mode == MODE_VI) { (void)adjmove(cursor, cursor, FINL); cursor = adjmove(cursor, tcurs, (int)(vikeys[prevkey].flags | FINL)); } /* cleanup */ prevkey = 0; } else if (!prevkey) { if (tcurs != MARK_UNSET) cursor = tcurs; } } }
vi() { register int key; /* keystroke from user */ long count; /* numeric argument to some functions */ register struct keystru *keyptr;/* pointer to vikeys[] element */ MARK tcurs; /* temporary cursor */ int prevkey;/* previous key, if d/c/y/</>/! */ MARK range; /* start of range for d/c/y/</>/! */ char text[100]; int dotkey; /* last "key" of a change */ int dotpkey;/* last "prevkey" of a change */ int dotkey2;/* last extra "getkey()" of a change */ int dotcnt; /* last "count" of a change */ register int i; /* tell the redraw() function to start from scratch */ redraw(MARK_UNSET, FALSE); msg((char *)0); #ifdef lint /* lint says that "range" might be used before it is set. This * can't really happen due to the way "range" and "prevkey" are used, * but lint doesn't know that. This line is here ONLY to keep lint * happy. */ range = 0L; #endif /* safeguard against '.' with no previous command */ dotkey = 0; /* Repeatedly handle VI commands */ for (count = 0, prevkey = '\0'; mode == MODE_VI; ) { /* if we've moved off the undoable line, then we can't undo it at all */ if (markline(cursor) != U_line) { U_line = 0L; } /* report any changes from the previous command */ if (rptlines >= *o_report) { redraw(cursor, FALSE); msg("%ld lines %s", rptlines, rptlabel); } rptlines = 0L; /* get the next command key. It must be ASCII */ do { key = getkey(WHEN_VICMD); } while (key < 0 || key > 127); /* change cw and cW commands to ce and cE, respectively */ /* (Why? because the real vi does it that way!) */ if (prevkey == 'c') { if (key == 'w') key = 'e'; else if (key == 'W') key = 'E'; /* wouldn't work right at the end of a word unless we * backspace one character before doing the move. This * will fix most cases. */ if (markidx(cursor) > 0 && (key == 'e' || key == 'E')) { cursor--; } } /* look up the structure describing this command */ keyptr = &vikeys[key]; /* if we're in the middle of a d/c/y/</>/! command, reject * anything but movement or a doubled version like "dd". */ if (prevkey && key != prevkey && !(keyptr->flags & (MVMT|PTMV))) { beep(); prevkey = 0; count = 0; continue; } /* set the "dot" variables, if we're supposed to */ if ((keyptr->flags & SDOT) || (prevkey && vikeys[prevkey].flags & SDOT)) { dotkey = key; dotpkey = prevkey; dotkey2 = '\0'; dotcnt = count; /* remember the line before any changes are made */ if (U_line != markline(cursor)) { U_line = markline(cursor); strcpy(U_text, fetchline(U_line)); } } /* if this is "." then set other vars from the "dot" vars */ if (key == '.') { key = dotkey; keyptr = &vikeys[key]; prevkey = dotpkey; if (prevkey) { range = cursor; } if (count == 0) { count = dotcnt; } doingdot = TRUE; /* remember the line before any changes are made */ if (U_line != markline(cursor)) { U_line = markline(cursor); strcpy(U_text, fetchline(U_line)); } } else { doingdot = FALSE; } /* process the key as a command */ tcurs = cursor; switch (keyptr->args) { case ZERO: if (count == 0) { tcurs = cursor & ~(BLKSIZE - 1); break; } /* else fall through & treat like other digits... */ case DIGIT: count = count * 10 + key - '0'; break; case KEYWORD: /* if not on a keyword, fail */ pfetch(markline(cursor)); key = markidx(cursor); if (!isalnum(ptext[key]) && ptext[key] != '_') { tcurs = MARK_UNSET; break; } /* find the start of the keyword */ while (key > 0 && (isalnum(ptext[key - 1]) || ptext[key - 1] == '_')) { key--; } /* copy it into a buffer, and NUL-terminate it */ i = 0; do { text[i++] = ptext[key++]; } while (isalnum(ptext[key]) || ptext[key] == '_'); text[i] = '\0'; /* call the function */ tcurs = (*keyptr->func)(text); count = 0L; break; case NO_ARGS: if (keyptr->func) { (*keyptr->func)(); } else { beep(); } count = 0L; break; case CURSOR_COUNT: tcurs = (*keyptr->func)(cursor, count); count = 0L; break; case CURSOR: tcurs = (*keyptr->func)(cursor); count = 0L; break; case CURSOR_CNT_KEY: if (doingdot) { tcurs = (*keyptr->func)(cursor, count, dotkey2); } else if (keyptr->flags & SDOT || (prevkey && vikeys[prevkey].flags & SDOT)) { dotkey2 = getkey(0); tcurs = (*keyptr->func)(cursor, count, dotkey2); } else { tcurs = (*keyptr->func)(cursor, count, getkey(0)); } count = 0L; break; case CURSOR_MOVED: /* uppercase keys always act like doubled */ if (isupper(key)) { prevkey = key; range = cursor; } if (prevkey) { /* doubling up a command, use complete lines */ range &= ~(BLKSIZE - 1); if (count) { tcurs = range + MARK_AT_LINE(count); count = 0; } else { tcurs = range + BLKSIZE; } } else { prevkey = key; range = cursor; key = -1; /* so we don't think we doubled yet */ } break; case CURSOR_EOL: /* act like CURSOR_MOVED with '$' movement */ range = cursor; tcurs = moverear(cursor, 1L); count = 0L; prevkey = key; key = '$'; keyptr = &vikeys['$']; break; case CURSOR_TEXT: if (vgets(key, text, sizeof text) >= 0) { /* reassure user that <CR> was hit */ qaddch('\r'); refresh(); /* call the function with the text */ tcurs = (*keyptr->func)(cursor, text); } count = 0L; break; case CURSOR_CNT_CMD: tcurs = (*keyptr->func)(cursor, count, key); count = 0L; break; } /* if that command took us out of vi mode, then exit the loop * NOW, without tweaking the cursor or anything. This is very * important when mode == MODE_QUIT. */ if (mode != MODE_VI) { break; } /* now move the cursor, as appropriate */ if (prevkey && markline(tcurs) > nlines) { /* destination for operator may be nlines + 1 */ cursor = MARK_AT_LINE(nlines + 1); } else if (keyptr->args == CURSOR_MOVED) { /* the < and > keys have FRNT, * but it shouldn't be applied yet */ cursor = adjmove(cursor, tcurs, 0); } else { cursor = adjmove(cursor, tcurs, keyptr->flags); } /* was that the end of a d/c/y/</>/! command? */ if (prevkey && (prevkey == key || (keyptr->flags & MVMT))) { /* if the movement command failed, cancel operation */ if (tcurs == MARK_UNSET) { prevkey = 0; count = 0; continue; } /* make sure range=front and tcurs=rear */ if (cursor < range) { tcurs = range; range = cursor; } else { tcurs = cursor; } /* adjust for line mode */ if (keyptr->flags & LNMD) { range &= ~(BLKSIZE - 1); tcurs &= ~(BLKSIZE - 1); tcurs += BLKSIZE; } /* adjust for inclusion of last char */ if (keyptr->flags & INCL) { tcurs++; } /* temporarily move the cursor to "range" so that * beforedo() remembers the cursor's real location. * This is important if the user later does undo() */ cursor = range; /* run the function */ tcurs = (*vikeys[prevkey].func)(range, tcurs); cursor = adjmove(cursor, tcurs, vikeys[prevkey].flags); /* cleanup */ prevkey = 0; } } }
/** * load IMCs from a configuration file */ static bool load_imcs(char *filename) { int fd, line_nr = 0; chunk_t src, line; struct stat sb; void *addr; DBG1(DBG_TNC, "loading IMCs from '%s'", filename); fd = open(filename, O_RDONLY); if (fd == -1) { DBG1(DBG_TNC, "opening configuration file '%s' failed: %s", filename, strerror(errno)); return FALSE; } if (fstat(fd, &sb) == -1) { DBG1(DBG_LIB, "getting file size of '%s' failed: %s", filename, strerror(errno)); close(fd); return FALSE; } addr = mmap(NULL, sb.st_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); if (addr == MAP_FAILED) { DBG1(DBG_LIB, "mapping '%s' failed: %s", filename, strerror(errno)); close(fd); return FALSE; } src = chunk_create(addr, sb.st_size); while (fetchline(&src, &line)) { char *name, *path; chunk_t token; imc_t *imc; line_nr++; /* skip comments or empty lines */ if (*line.ptr == '#' || !eat_whitespace(&line)) { continue; } /* determine keyword */ if (!extract_token(&token, ' ', &line)) { DBG1(DBG_TNC, "line %d: keyword must be followed by a space", line_nr); return FALSE; } /* only interested in IMCs */ if (!match("IMC", &token)) { continue; } /* advance to the IMC name and extract it */ if (!extract_token(&token, '"', &line) || !extract_token(&token, '"', &line)) { DBG1(DBG_TNC, "line %d: IMC name must be set in double quotes", line_nr); return FALSE; } /* copy the IMC name */ name = malloc(token.len + 1); memcpy(name, token.ptr, token.len); name[token.len] = '\0'; /* advance to the IMC path and extract it */ if (!eat_whitespace(&line)) { DBG1(DBG_TNC, "line %d: IMC path is missing", line_nr); free(name); return FALSE; } if (!extract_token(&token, ' ', &line)) { token = line; } /* copy the IMC path */ path = malloc(token.len + 1); memcpy(path, token.ptr, token.len); path[token.len] = '\0'; /* load and register IMC instance */ imc = tnc_imc_create(name, path); if (!imc) { free(name); free(path); return FALSE; } if (!charon->imcs->add(charon->imcs, imc)) { if (imc->terminate && imc->terminate(imc->get_id(imc)) != TNC_RESULT_SUCCESS) { DBG1(DBG_TNC, "IMC \"%s\" not terminated successfully", imc->get_name(imc)); } imc->destroy(imc); return FALSE; } DBG1(DBG_TNC, "IMC %u \"%s\" loaded from '%s'", imc->get_id(imc), name, path); } munmap(addr, sb.st_size); close(fd); return TRUE; }
void command_loop(void) { int c, i, j = 0, done = 0, fetchable = 0, prompted = 0; char *input; char **v; const cmdinfo_t *ct; for (i = 0; !done && i < ncmdline; i++) { input = strdup(cmdline[i]); if (!input) { fprintf(stderr, _("cannot strdup command '%s': %s\n"), cmdline[i], strerror(errno)); exit(1); } v = breakline(input, &c); if (c) { ct = find_command(v[0]); if (ct) { if (ct->flags & CMD_FLAG_GLOBAL) { done = command(ct, c, v); } else { j = 0; while (!done && (j = args_command(j))) { done = command(ct, c, v); } } } else { fprintf(stderr, _("command \"%s\" not found\n"), v[0]); } } doneline(input, v); } if (cmdline) { g_free(cmdline); return; } while (!done) { if (!prompted) { printf("%s", get_prompt()); fflush(stdout); qemu_aio_set_fd_handler(STDIN_FILENO, prep_fetchline, NULL, NULL, NULL, &fetchable); prompted = 1; } qemu_aio_wait(); if (!fetchable) { continue; } input = fetchline(); if (input == NULL) { break; } v = breakline(input, &c); if (c) { ct = find_command(v[0]); if (ct) { done = command(ct, c, v); } else { fprintf(stderr, _("command \"%s\" not found\n"), v[0]); } } doneline(input, v); prompted = 0; fetchable = 0; } qemu_aio_set_fd_handler(STDIN_FILENO, NULL, NULL, NULL, NULL, NULL); }
/** * Converts a PEM encoded file into its binary form (RFC 1421, RFC 934) */ static status_t pem_to_bin(chunk_t *blob, bool *pgp) { typedef enum { PEM_PRE = 0, PEM_MSG = 1, PEM_HEADER = 2, PEM_BODY = 3, PEM_POST = 4, PEM_ABORT = 5 } state_t; encryption_algorithm_t alg = ENCR_UNDEFINED; size_t key_size = 0; bool encrypted = FALSE; state_t state = PEM_PRE; chunk_t src = *blob; chunk_t dst = *blob; chunk_t line = chunk_empty; chunk_t iv = chunk_empty; u_char iv_buf[HASH_SIZE_MD5]; status_t status = NOT_FOUND; enumerator_t *enumerator; shared_key_t *shared; dst.len = 0; iv.ptr = iv_buf; iv.len = 0; while (fetchline(&src, &line)) { if (state == PEM_PRE) { if (find_boundary("BEGIN", &line)) { state = PEM_MSG; } continue; } else { if (find_boundary("END", &line)) { state = PEM_POST; break; } if (state == PEM_MSG) { state = PEM_HEADER; if (memchr(line.ptr, ':', line.len) == NULL) { state = PEM_BODY; } } if (state == PEM_HEADER) { err_t ugh = NULL; chunk_t name = chunk_empty; chunk_t value = chunk_empty; /* an empty line separates HEADER and BODY */ if (line.len == 0) { state = PEM_BODY; continue; } /* we are looking for a parameter: value pair */ DBG2(DBG_ASN, " %.*s", (int)line.len, line.ptr); ugh = extract_parameter_value(&name, &value, &line); if (ugh != NULL) { continue; } if (match("Proc-Type", &name) && *value.ptr == '4') { encrypted = TRUE; } else if (match("DEK-Info", &name)) { chunk_t dek; if (!extract_token(&dek, ',', &value)) { dek = value; } if (match("DES-EDE3-CBC", &dek)) { alg = ENCR_3DES; key_size = 24; } else if (match("AES-128-CBC", &dek)) { alg = ENCR_AES_CBC; key_size = 16; } else if (match("AES-192-CBC", &dek)) { alg = ENCR_AES_CBC; key_size = 24; } else if (match("AES-256-CBC", &dek)) { alg = ENCR_AES_CBC; key_size = 32; } else { DBG1(DBG_ASN, " encryption algorithm '%.*s'" " not supported", (int)dek.len, dek.ptr); return NOT_SUPPORTED; } if (!eat_whitespace(&value) || value.len > 2*sizeof(iv_buf)) { return PARSE_ERROR; } iv = chunk_from_hex(value, iv_buf); } } else /* state is PEM_BODY */ { chunk_t data; /* remove any trailing whitespace */ if (!extract_token(&data ,' ', &line)) { data = line; } /* check for PGP armor checksum */ if (*data.ptr == '=') { *pgp = TRUE; data.ptr++; data.len--; DBG2(DBG_ASN, " armor checksum: %.*s", (int)data.len, data.ptr); continue; } if (blob->len - dst.len < data.len / 4 * 3) { state = PEM_ABORT; } data = chunk_from_base64(data, dst.ptr); dst.ptr += data.len; dst.len += data.len; } } } /* set length to size of binary blob */ blob->len = dst.len; if (state != PEM_POST) { DBG1(DBG_LIB, " file coded in unknown format, discarded"); return PARSE_ERROR; } if (!encrypted) { return SUCCESS; } enumerator = lib->credmgr->create_shared_enumerator(lib->credmgr, SHARED_PRIVATE_KEY_PASS, NULL, NULL); while (enumerator->enumerate(enumerator, &shared, NULL, NULL)) { chunk_t passphrase, chunk; passphrase = shared->get_key(shared); chunk = chunk_clone(*blob); status = pem_decrypt(&chunk, alg, key_size, iv, passphrase); if (status == SUCCESS) { memcpy(blob->ptr, chunk.ptr, chunk.len); blob->len = chunk.len; } free(chunk.ptr); if (status != INVALID_ARG) { /* try again only if passphrase invalid */ break; } } enumerator->destroy(enumerator); return status; }
/** * Converts a PEM encoded file into its binary form (RFC 1421, RFC 934) */ static status_t pem_to_bin(chunk_t *blob, chunk_t(*cb)(void*,int), void *cb_data, bool *pgp) { typedef enum { PEM_PRE = 0, PEM_MSG = 1, PEM_HEADER = 2, PEM_BODY = 3, PEM_POST = 4, PEM_ABORT = 5 } state_t; encryption_algorithm_t alg = ENCR_UNDEFINED; size_t key_size = 0; bool encrypted = FALSE; state_t state = PEM_PRE; chunk_t src = *blob; chunk_t dst = *blob; chunk_t line = chunk_empty; chunk_t iv = chunk_empty; chunk_t passphrase; int try = 0; u_char iv_buf[HASH_SIZE_MD5]; dst.len = 0; iv.ptr = iv_buf; iv.len = 0; while (fetchline(&src, &line)) { if (state == PEM_PRE) { if (find_boundary("BEGIN", &line)) { state = PEM_MSG; } continue; } else { if (find_boundary("END", &line)) { state = PEM_POST; break; } if (state == PEM_MSG) { state = PEM_HEADER; if (memchr(line.ptr, ':', line.len) == NULL) { state = PEM_BODY; } } if (state == PEM_HEADER) { err_t ugh = NULL; chunk_t name = chunk_empty; chunk_t value = chunk_empty; /* an empty line separates HEADER and BODY */ if (line.len == 0) { state = PEM_BODY; continue; } /* we are looking for a parameter: value pair */ DBG2(DBG_LIB, " %.*s", (int)line.len, line.ptr); ugh = extract_parameter_value(&name, &value, &line); if (ugh != NULL) { continue; } if (match("Proc-Type", &name) && *value.ptr == '4') { encrypted = TRUE; } else if (match("DEK-Info", &name)) { chunk_t dek; if (!extract_token(&dek, ',', &value)) { dek = value; } if (match("DES-EDE3-CBC", &dek)) { alg = ENCR_3DES; key_size = 24; } else if (match("AES-128-CBC", &dek)) { alg = ENCR_AES_CBC; key_size = 16; } else if (match("AES-192-CBC", &dek)) { alg = ENCR_AES_CBC; key_size = 24; } else if (match("AES-256-CBC", &dek)) { alg = ENCR_AES_CBC; key_size = 32; } else { DBG1(DBG_LIB, " encryption algorithm '%.*s'" " not supported", dek.len, dek.ptr); return NOT_SUPPORTED; } eat_whitespace(&value); iv = chunk_from_hex(value, iv.ptr); } } else /* state is PEM_BODY */ { chunk_t data; /* remove any trailing whitespace */ if (!extract_token(&data ,' ', &line)) { data = line; } /* check for PGP armor checksum */ if (*data.ptr == '=') { *pgp = TRUE; data.ptr++; data.len--; DBG2(DBG_LIB, " armor checksum: %.*s", (int)data.len, data.ptr); continue; } if (blob->len - dst.len < data.len / 4 * 3) { state = PEM_ABORT; } data = chunk_from_base64(data, dst.ptr); dst.ptr += data.len; dst.len += data.len; } } } /* set length to size of binary blob */ blob->len = dst.len; if (state != PEM_POST) { DBG1(DBG_LIB, " file coded in unknown format, discarded"); return PARSE_ERROR; } if (!encrypted) { return SUCCESS; } if (!cb) { DBG1(DBG_LIB, " missing passphrase"); return INVALID_ARG; } while (TRUE) { passphrase = cb(cb_data, ++try); if (!passphrase.len || !passphrase.ptr) { return INVALID_ARG; } switch (pem_decrypt(blob, alg, key_size, iv, passphrase)) { case INVALID_ARG: /* bad passphrase, retry */ continue; case SUCCESS: return SUCCESS; default: return FAILED; } } }
/* * Converts a PEM encoded file into its binary form * * RFC 1421 Privacy Enhancement for Electronic Mail, February 1993 * RFC 934 Message Encapsulation, January 1985 * * We no longer support decrypting PEM files - those can only come in via NSS */ err_t pemtobin(chunk_t *blob) { typedef enum { PEM_PRE = 0, PEM_MSG = 1, PEM_HEADER = 2, PEM_BODY = 3, PEM_POST = 4, PEM_ABORT = 5 } state_t; state_t state = PEM_PRE; chunk_t src = *blob; chunk_t dst = *blob; chunk_t line = empty_chunk; /* zero size of converted blob */ dst.len = 0; while (fetchline(&src, &line)) { if (state == PEM_PRE) { if (find_boundary("BEGIN", &line)) { state = PEM_MSG; } continue; } else { if (find_boundary("END", &line)) { state = PEM_POST; break; } if (state == PEM_MSG) { state = (memchr(line.ptr, ':', line.len) == NULL) ? PEM_BODY : PEM_HEADER; } if (state == PEM_HEADER) { chunk_t name = empty_chunk; chunk_t value = empty_chunk; /* an empty line separates HEADER and BODY */ if (line.len == 0) { state = PEM_BODY; continue; } /* we are looking for a name: value pair */ if (!extract_parameter(&name, &value, &line)) continue; if (match("Proc-Type", &name) && *value.ptr == '4') return "Proc-Type: encrypted files no longer supported outside of the NSS database, please import these into NSS"; else if (match("DEK-Info", &name)) return "DEK-Info: encrypted files no longer supported outside of the NSS database, please import these into NSS"; } else { /* state is PEM_BODY */ const char *ugh = NULL; size_t len = 0; chunk_t data; /* remove any trailing whitespace */ if (!extract_token(&data, ' ', &line)) data = line; ugh = ttodata((char *)data.ptr, data.len, 64, (char *)dst.ptr, blob->len - dst.len, &len); if (ugh) { DBG(DBG_PARSING, DBG_log(" %s", ugh)); state = PEM_ABORT; break; } else { dst.ptr += len; dst.len += len; } } } } /* set length to size of binary blob */ blob->len = dst.len; if (state != PEM_POST) return "file coded in unknown format, discarded"; return NULL; }
int main(int argc, char *argv[]) { xfs_mount_t *mp; xfs_inode_t *inode = NULL; xfs_off_t ofs; struct filldir_data filldata; char *progname; char *source_name; int r, fd; char *line; char path[FILENAME_MAX] = "/"; char newpath[FILENAME_MAX] = "/"; char *buffer[BUFSIZE]; off_t offset; if (argc != 2) { printf("Usage: xfs-cli raw_device\n"); return 1; } progname = argv[0]; source_name = argv[1]; mp = mount_xfs(progname, source_name); if (mp == NULL) return 1; while (line == fetchline(mp, path)) { inode = NULL; strip(line, ' '); if (strncmp(line, "cd ", 3) == 0) { if (strcmp(line+3, "..") == 0) { goto_parent(path); } else { strcpy(newpath, path); strcat(newpath, line+3); r = find_path(mp, newpath, &inode); if ((!r) && (xfs_is_dir(inode))) { //TODO: check if it is a directory strcpy(path, newpath); strcat(path, "/"); printf("%s\n", path); } else { if (r) { printf("No such directory\n"); } else { printf("Not a directory\n"); } } } } else if (strcmp(line, "ls") == 0) { r = find_path(mp, path, &inode); if (!r) { //TODO: check if it is a directory ofs=0; filldata.mp = mp; filldata.base = inode; r = xfs_readdir(inode, (void *)&filldata, 102400, &ofs, cli_ls_xfs_filldir); if (r != 0) { printf("Not a directory\n"); } } else { printf("No such directory\n"); } } else if (strncmp(line, "cat ", 4) == 0) { strcpy(newpath, path); strcat(newpath, line+4); r = find_path(mp, newpath, &inode); if (r) printf("File not found\n"); else if (xfs_is_regular(inode)) { //TODO: check if it is a file r = 10; offset = 0; while (r) { r = xfs_readfile(inode, buffer, offset, BUFSIZE, NULL); if (r) { write(1, buffer, r); offset += r; } } } else if (xfs_is_link(inode)) { r = 10; offset = 0; while (r) { r = xfs_readlink(inode, buffer, offset, BUFSIZE, NULL); if (r) { write(1, buffer, r); offset += r; } } } else { printf("Not a regular file\n"); } } else if (strncmp(line, "get ", 4) == 0) { strcpy(newpath, path); strcat(newpath, line+4); r = find_path(mp, newpath, &inode); if ((!r) && (xfs_is_regular(inode))) { //TODO: check if it is a file r = 10; offset = 0; fd = open(line+4, O_WRONLY|O_CREAT, 0660); if (fd < 0) { printf("Failed to open local file\n"); } else { while (r) { r = xfs_readfile(inode, buffer, offset, BUFSIZE, NULL); if (r) { write(fd, buffer, r); offset += r; } } close(fd); printf("Retrieved %ld bytes\n", offset); } } else { if (r) printf("File not found\n"); else printf("Not a regular file\n"); } } else if (strcmp(line, "exit") == 0) { libxfs_umount(mp); return 0; } else if (strcmp(line, "pwd") == 0) { printf("%s\n", path); } else { printf("Unknown command\n"); } free(line); if (inode) { libxfs_iput(inode, 0); } } libxfs_umount(mp); return 0; }