static STREAM cssp_encode_tspasswordcreds(char *username, char *password, char *domain) { STREAM out, h1, h2; struct stream tmp = { 0 }; struct stream message = { 0 }; memset(&tmp, 0, sizeof(tmp)); memset(&message, 0, sizeof(message)); // domainName [0] s_realloc(&tmp, 4 + strlen(domain) * sizeof(uint16)); s_reset(&tmp); rdp_out_unistr(&tmp, domain, strlen(domain) * sizeof(uint16)); s_mark_end(&tmp); h2 = ber_wrap_hdr_data(BER_TAG_OCTET_STRING, &tmp); h1 = ber_wrap_hdr_data(BER_TAG_CTXT_SPECIFIC | BER_TAG_CONSTRUCTED | 0, h2); s_realloc(&message, s_length(&message) + s_length(h1)); out_uint8p(&message, h1->data, s_length(h1)); s_mark_end(&message); s_free(h2); s_free(h1); // userName [1] s_realloc(&tmp, 4 + strlen(username) * sizeof(uint16)); s_reset(&tmp); rdp_out_unistr(&tmp, username, strlen(username) * sizeof(uint16)); s_mark_end(&tmp); h2 = ber_wrap_hdr_data(BER_TAG_OCTET_STRING, &tmp); h1 = ber_wrap_hdr_data(BER_TAG_CTXT_SPECIFIC | BER_TAG_CONSTRUCTED | 1, h2); s_realloc(&message, s_length(&message) + s_length(h1)); out_uint8p(&message, h1->data, s_length(h1)); s_mark_end(&message); s_free(h2); s_free(h1); // password [2] s_realloc(&tmp, 4 + strlen(password) * sizeof(uint16)); s_reset(&tmp); rdp_out_unistr(&tmp, password, strlen(password) * sizeof(uint16)); s_mark_end(&tmp); h2 = ber_wrap_hdr_data(BER_TAG_OCTET_STRING, &tmp); h1 = ber_wrap_hdr_data(BER_TAG_CTXT_SPECIFIC | BER_TAG_CONSTRUCTED | 2, h2); s_realloc(&message, s_length(&message) + s_length(h1)); out_uint8p(&message, h1->data, s_length(h1)); s_mark_end(&message); s_free(h2); s_free(h1); // build message out = ber_wrap_hdr_data(BER_TAG_SEQUENCE | BER_TAG_CONSTRUCTED, &message); // cleanup xfree(tmp.data); xfree(message.data); return out; }
NODE* invalid_token(SCANNER *s) { char buf[BUFSIZ], c; size_t i, l, o; long pos = s_pos(s); snprintf(buf, sizeof(buf)-1, "invalid token at offset %ld", pos == -1 ? 0 : pos); l = strlen(buf); s_reset(s); if (!isatty(fileno(stdin))) { buf[l++] = '\n'; o = l; for (i = 0; l < sizeof(buf)-1; i++) { c = s_getc(s); if (s_eof(s)) break; if (c == '\n') { if (i >= (size_t)pos) break; l = o; continue; } buf[l++] = c; } buf[l] = 0; } s->err = strdup(buf); return NULL; }
/// Stat stdout and stderr and compare result to previous result in reader_save_status. Repaint if /// modification time has changed. /// /// Unfortunately, for some reason this call seems to give a lot of false positives, at least under /// Linux. static void s_check_status(screen_t *s) { fflush(stdout); fflush(stderr); fstat(1, &s->post_buff_1); fstat(2, &s->post_buff_2); int changed = (s->prev_buff_1.st_mtime != s->post_buff_1.st_mtime) || (s->prev_buff_2.st_mtime != s->post_buff_2.st_mtime); #if defined HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC changed = changed || s->prev_buff_1.st_mtimespec.tv_nsec != s->post_buff_1.st_mtimespec.tv_nsec || s->prev_buff_2.st_mtimespec.tv_nsec != s->post_buff_2.st_mtimespec.tv_nsec; #elif defined HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC changed = changed || s->prev_buff_1.st_mtim.tv_nsec != s->post_buff_1.st_mtim.tv_nsec || s->prev_buff_2.st_mtim.tv_nsec != s->post_buff_2.st_mtim.tv_nsec; #endif if (changed) { // Ok, someone has been messing with our screen. We will want to repaint. However, we do not // know where the cursor is. It is our best bet that we are still on the same line, so we // move to the beginning of the line, reset the modelled screen contents, and then set the // modeled cursor y-pos to its earlier value. int prev_line = s->actual.cursor.y; write_loop(STDOUT_FILENO, "\r", 1); s_reset(s, screen_reset_current_line_and_prompt); s->actual.cursor.y = prev_line; } }
parser_state * PyParser_New(grammar *g, int start) { parser_state *ps; DBP("Attempting to create new PyParser\n"); if (!g->g_accel) PyGrammar_AddAccelerators(g); DBP("Added grammar accelerators\n"); ps = (parser_state *)PyMem_MALLOC(sizeof(parser_state)); DBP("Created parser state\n"); if (ps == NULL) return NULL; ps->p_grammar = g; #ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD ps->p_flags = 0; #endif ps->p_tree = PyNode_New(start); if (ps->p_tree == NULL) { PyMem_FREE(ps); return NULL; } s_reset(&ps->p_stack); (void) s_push(&ps->p_stack, PyGrammar_FindDFA(g, start), ps->p_tree); DBP("Created PyParser!!\n"); return ps; }
void main(int argc, char **argv) { int i; Biobuf *b; String *h; Whist *doc; ARGBEGIN{ default: usage(); case 'd': wikidir = EARGF(usage()); break; }ARGEND if(argc != 1) usage(); if((b = Bopen(argv[0], OREAD)) == nil) sysfatal("Bopen: %r"); if((doc = Brdwhist(b)) == nil) sysfatal("Brdwtxt: %r"); h = nil; for(i=0; i<doc->ndoc; i++){ print("__________________ %d ______________\n", i); if((h = pagetext(s_reset(h), doc->doc[i].wtxt, 1)) == nil) sysfatal("wiki2html: %r"); write(1, s_to_c(h), s_len(h)); } exits(0); }
static void s_check_status( screen_t *s) { fflush( stdout ); fflush( stderr ); fstat( 1, &s->post_buff_1 ); fstat( 2, &s->post_buff_2 ); int changed = ( s->prev_buff_1.st_mtime != s->post_buff_1.st_mtime ) || ( s->prev_buff_2.st_mtime != s->post_buff_2.st_mtime ); if (room_for_usec( &s->post_buff_1)) { changed = changed || ( (&s->prev_buff_1.st_mtime)[1] != (&s->post_buff_1.st_mtime)[1] ) || ( (&s->prev_buff_2.st_mtime)[1] != (&s->post_buff_2.st_mtime)[1] ); } if( changed ) { /* Ok, someone has been messing with our screen. We will want to repaint. However, we do not know where the cursor is. It is our best bet that we are still on the same line, so we move to the beginning of the line, reset the modelled screen contents, and then set the modeled cursor y-pos to its earlier value. */ int prev_line = s->actual_cursor[1]; write_loop( 1, "\r", 1 ); s_reset( s, 0 ); s->actual_cursor[1] = prev_line; } }
/* * add a domain onto an name, return the new name */ char * domainify(char *name, char *domain) { static String *s; char *p; if(domain==0 || strchr(name, '.')!=0) return name; s = s_reset(s); s_append(s, name); p = strchr(domain, '.'); if(p == 0){ s_append(s, "."); p = domain; } s_append(s, p); return s_to_c(s); }
static int rreadstr(char *delim, char *s) /* if s != 0, skip this chars before reading */ { int c; s_reset(sbuf); if(s) skip(s); while((c=GETC()) >= 0){ if(strchr(delim, c)){ UNGETC(c); s_terminate(sbuf); return Tstring; } s_putc(sbuf, c); } if(c == Beof) yyerror("eof in string"); return Terror; }
parser_state * PyParser_New(grammar *g, int start) { parser_state *ps; if (!g->g_accel) PyGrammar_AddAccelerators(g); ps = PyMem_NEW(parser_state, 1); if (ps == NULL) return NULL; ps->p_grammar = g; ps->p_generators = 0; ps->p_tree = PyNode_New(start); if (ps->p_tree == NULL) { PyMem_DEL(ps); return NULL; } s_reset(&ps->p_stack); (void) s_push(&ps->p_stack, PyGrammar_FindDFA(g, start), ps->p_tree); return ps; }
static void addtreetoar(int ar, char *file, char *shortf, int fd) { int n; Dir *dent, *dirents; String *name = s_new(); n = dirreadall(fd, &dirents); if (n < 0) fprint(2, "%s: dirreadall %s: %r\n", argv0, file); close(fd); if (n <= 0) return; if (chdir(shortf) < 0) sysfatal("chdir %s: %r", file); if (Debug) fprint(2, "chdir %s\t# %s\n", shortf, file); for (dent = dirents; dent < dirents + n; dent++) { s_reset(name); s_append(name, file); s_append(name, "/"); s_append(name, dent->name); addtoar(ar, s_to_c(name), dent->name); } s_free(name); free(dirents); /* * this assumes that shortf is just one component, which is true * during directory descent, but not necessarily true of command-line * arguments. Our caller (or addtoar's) must reset the working * directory if necessary. */ if (chdir("..") < 0) sysfatal("chdir %s/..: %r", file); if (Debug) fprint(2, "chdir ..\n"); }
static int readname(char *s) { int c; s_reset(sbuf); if(s) skip(s); while((c=GETC()) >= 0 && (isalnum(c) || c == '-')) s_putc(sbuf, c); if(c == Beof){ yyerror("eof in id/class"); return Terror; } UNGETC(c); if(s_len(sbuf) == 0){ yyerror("empty name"); return Terror; } s_terminate(sbuf); return Tstring; }
parser_state * Ta27Parser_New(grammar *g, int start) { parser_state *ps; if (!g->g_accel) Ta27Grammar_AddAccelerators(g); ps = (parser_state *)PyMem_MALLOC(sizeof(parser_state)); if (ps == NULL) return NULL; ps->p_grammar = g; #ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD ps->p_flags = 0; #endif ps->p_tree = Ta27Node_New(start); if (ps->p_tree == NULL) { PyMem_FREE(ps); return NULL; } s_reset(&ps->p_stack); (void) s_push(&ps->p_stack, Ta27Grammar_FindDFA(g, start), ps->p_tree); return ps; }
/* * read a reply into a string, return the reply code */ int getreply(void) { char *line; int rv; reply = s_reset(reply); for(;;){ line = getcrnl(reply); if(debug) Bflush(&berr); if(line == 0) return -1; if(!isdigit(line[0]) || !isdigit(line[1]) || !isdigit(line[2])) return -1; if(line[3] != '-') break; } if(debug) Bflush(&berr); rv = atoi(line)/100; return rv; }
char * convert(Rune *s) { static String *sbuf; int i, n, state; char buf[JISmax]; if (sbuf == nil) { sbuf = s_new(); if (sbuf == nil) sysfatal("s_new: %r"); } state = 0; s_reset(sbuf); for ( ; *s; s++) { switch (chset) { case EUC_JP: n = runetoujis(buf, s); break; case ISO_2022_JP: n = runetojis(buf, s, &state); break; case Shift_JIS: n = runetosjis(buf, s); break; default: n = runetochar(buf, s); break; } for (i = 0; i < n; i++) escape(sbuf, buf[i]); } s_putc(sbuf, '\0'); return estrdup(s_to_c(sbuf)); }
/// Stat stdout and stderr and compare result to previous result in reader_save_status. Repaint if /// modification time has changed. /// /// Unfortunately, for some reason this call seems to give a lot of false positives, at least under /// Linux. static void s_check_status(screen_t *s) { fflush(stdout); fflush(stderr); if (!has_working_tty_timestamps) { // We can't reliably determine if the terminal has been written to behind our back so we // just assume that hasn't happened and hope for the best. This is important for multi-line // prompts to work correctly. return; } fstat(1, &s->post_buff_1); fstat(2, &s->post_buff_2); bool changed = (s->prev_buff_1.st_mtime != s->post_buff_1.st_mtime) || (s->prev_buff_2.st_mtime != s->post_buff_2.st_mtime); #if defined HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC changed = changed || s->prev_buff_1.st_mtimespec.tv_nsec != s->post_buff_1.st_mtimespec.tv_nsec || s->prev_buff_2.st_mtimespec.tv_nsec != s->post_buff_2.st_mtimespec.tv_nsec; #elif defined HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC changed = changed || s->prev_buff_1.st_mtim.tv_nsec != s->post_buff_1.st_mtim.tv_nsec || s->prev_buff_2.st_mtim.tv_nsec != s->post_buff_2.st_mtim.tv_nsec; #endif if (changed) { // Ok, someone has been messing with our screen. We will want to repaint. However, we do not // know where the cursor is. It is our best bet that we are still on the same line, so we // move to the beginning of the line, reset the modelled screen contents, and then set the // modeled cursor y-pos to its earlier value. int prev_line = s->actual.cursor.y; write_loop(STDOUT_FILENO, "\r", 1); s_reset(s, screen_reset_current_line_and_prompt); s->actual.cursor.y = prev_line; } }
/// Update the screen to match the desired output. static void s_update(screen_t *scr, const wcstring &left_prompt, const wcstring &right_prompt) { const environment_t &vars = env_stack_t::principal(); const scoped_buffer_t buffering(*scr); const size_t left_prompt_width = calc_prompt_layout(left_prompt, cached_layouts).last_line_width; const size_t right_prompt_width = calc_prompt_layout(right_prompt, cached_layouts).last_line_width; int screen_width = common_get_width(); // Figure out how many following lines we need to clear (probably 0). size_t actual_lines_before_reset = scr->actual_lines_before_reset; scr->actual_lines_before_reset = 0; bool need_clear_lines = scr->need_clear_lines; bool need_clear_screen = scr->need_clear_screen; bool has_cleared_screen = false; if (scr->actual_width != screen_width) { // Ensure we don't issue a clear screen for the very first output, to avoid issue #402. if (scr->actual_width != SCREEN_WIDTH_UNINITIALIZED) { need_clear_screen = true; s_move(scr, 0, 0); s_reset(scr, screen_reset_current_line_contents); need_clear_lines = need_clear_lines || scr->need_clear_lines; need_clear_screen = need_clear_screen || scr->need_clear_screen; } scr->actual_width = screen_width; } scr->need_clear_lines = false; scr->need_clear_screen = false; // Determine how many lines have stuff on them; we need to clear lines with stuff that we don't // want. const size_t lines_with_stuff = std::max(actual_lines_before_reset, scr->actual.line_count()); if (left_prompt != scr->actual_left_prompt) { s_move(scr, 0, 0); s_write_str(scr, left_prompt.c_str()); scr->actual_left_prompt = left_prompt; scr->actual.cursor.x = (int)left_prompt_width; } for (size_t i = 0; i < scr->desired.line_count(); i++) { const line_t &o_line = scr->desired.line(i); line_t &s_line = scr->actual.create_line(i); size_t start_pos = i == 0 ? left_prompt_width : 0; int current_width = 0; // If this is the last line, maybe we should clear the screen. const bool should_clear_screen_this_line = need_clear_screen && i + 1 == scr->desired.line_count() && clr_eos != NULL; // Note that skip_remaining is a width, not a character count. size_t skip_remaining = start_pos; if (!should_clear_screen_this_line) { // Compute how much we should skip. At a minimum we skip over the prompt. But also skip // over the shared prefix of what we want to output now, and what we output before, to // avoid repeatedly outputting it. const size_t shared_prefix = line_shared_prefix(o_line, s_line); if (shared_prefix > 0) { size_t prefix_width = fish_wcswidth(&o_line.text.at(0), shared_prefix); if (prefix_width > skip_remaining) skip_remaining = prefix_width; } // If we're soft wrapped, and if we're going to change the first character of the next // line, don't skip over the last two characters so that we maintain soft-wrapping. if (o_line.is_soft_wrapped && i + 1 < scr->desired.line_count()) { bool next_line_will_change = true; if (i + 1 < scr->actual.line_count()) { //!OCLINT if (line_shared_prefix(scr->desired.line(i + 1), scr->actual.line(i + 1)) > 0) { next_line_will_change = false; } } if (next_line_will_change) { skip_remaining = std::min(skip_remaining, (size_t)(scr->actual_width - 2)); } } } // Skip over skip_remaining width worth of characters. size_t j = 0; for (; j < o_line.size(); j++) { size_t width = fish_wcwidth_min_0(o_line.char_at(j)); if (skip_remaining < width) break; skip_remaining -= width; current_width += width; } // Skip over zero-width characters (e.g. combining marks at the end of the prompt). for (; j < o_line.size(); j++) { int width = fish_wcwidth_min_0(o_line.char_at(j)); if (width > 0) break; } // Now actually output stuff. for (; j < o_line.size(); j++) { // If we are about to output into the last column, clear the screen first. If we clear // the screen after we output into the last column, it can erase the last character due // to the sticky right cursor. If we clear the screen too early, we can defeat soft // wrapping. if (j + 1 == (size_t)screen_width && should_clear_screen_this_line && !has_cleared_screen) { s_move(scr, current_width, (int)i); s_write_mbs(scr, clr_eos); has_cleared_screen = true; } perform_any_impending_soft_wrap(scr, current_width, (int)i); s_move(scr, current_width, (int)i); s_set_color(scr, vars, o_line.color_at(j)); s_write_char(scr, o_line.char_at(j)); current_width += fish_wcwidth_min_0(o_line.char_at(j)); } // Clear the screen if we have not done so yet. if (should_clear_screen_this_line && !has_cleared_screen) { s_move(scr, current_width, (int)i); s_write_mbs(scr, clr_eos); has_cleared_screen = true; } bool clear_remainder = false; // Clear the remainder of the line if we need to clear and if we didn't write to the end of // the line. If we did write to the end of the line, the "sticky right edge" (as part of // auto_right_margin) means that we'll be clearing the last character we wrote! if (has_cleared_screen) { // Already cleared everything. clear_remainder = false; } else if (need_clear_lines && current_width < screen_width) { clear_remainder = true; } else if (right_prompt_width < scr->last_right_prompt_width) { clear_remainder = true; } else { int prev_width = s_line.text.empty() ? 0 : fish_wcswidth(&s_line.text.at(0), s_line.text.size()); clear_remainder = prev_width > current_width; } if (clear_remainder && clr_eol) { s_set_color(scr, vars, highlight_spec_t{}); s_move(scr, current_width, (int)i); s_write_mbs(scr, clr_eol); } // Output any rprompt if this is the first line. if (i == 0 && right_prompt_width > 0) { //!OCLINT(Use early exit/continue) s_move(scr, (int)(screen_width - right_prompt_width), (int)i); s_set_color(scr, vars, highlight_spec_t{}); s_write_str(scr, right_prompt.c_str()); scr->actual.cursor.x += right_prompt_width; // We output in the last column. Some terms (Linux) push the cursor further right, past // the window. Others make it "stick." Since we don't really know which is which, issue // a cr so it goes back to the left. // // However, if the user is resizing the window smaller, then it's possible the cursor // wrapped. If so, then a cr will go to the beginning of the following line! So instead // issue a bunch of "move left" commands to get back onto the line, and then jump to the // front of it. s_move(scr, scr->actual.cursor.x - (int)right_prompt_width, scr->actual.cursor.y); s_write_str(scr, L"\r"); scr->actual.cursor.x = 0; } } // Clear remaining lines (if any) if we haven't cleared the screen. if (!has_cleared_screen && scr->desired.line_count() < lines_with_stuff && clr_eol) { s_set_color(scr, vars, highlight_spec_t{}); for (size_t i = scr->desired.line_count(); i < lines_with_stuff; i++) { s_move(scr, 0, (int)i); s_write_mbs(scr, clr_eol); } } s_move(scr, scr->desired.cursor.x, scr->desired.cursor.y); s_set_color(scr, vars, highlight_spec_t{}); // We have now synced our actual screen against our desired screen. Note that this is a big // assignment! scr->actual = scr->desired; scr->last_right_prompt_width = right_prompt_width; }
int yylex(void) { int c, r; char c1; Sym *s; genblock: if(block != nblock){ if(block > nblock){ if(debug) fprint(2, "%s %d -> %d\n", ty(Tend), block, nblock); block--; return Tend; }else{ if(debug) fprint(2, "%s %d -> %d\n", ty(Tbegin), block, nblock); block++; return Tbegin; } } c = GETC(); if(c == Beof){ nblock = 0; if(block != nblock) goto genblock; return 0; } UNGETC(c); switch(state){ case Head0: /* [%type] string */ c = GETC(); if(c != '%'){ UNGETC(c); setstate(Body0); goto genblock; } r = readname(" \t"); if(r == Terror) return fail(Head2); s = lookup(s_to_c(sbuf)); yylval.sym = s; if(debug) fprint(2, "Sym[%s] %s\n", ty(s->type), s->name); setstate(Head1); return s->type; case Head1: /* %type [string] */ r = readstr("\n", " \t", 0); if(r == Terror) return fail(Head2); yylval.s = estrdup(s_to_c(sbuf)); if(debug) fprint(2, "%s %q\n", ty(Tstring), yylval.s); setstate(Head2); return Tstring; case Head2: skip(" \t"); c = GETC(); assert(c == '\n' || c == Beof); setstate(Head0); return ';'; case Body0: /* [indent] cmd inline */ c = GETC(); if(c == '%'){ UNGETC(c); setstate(Head0); goto genblock; } UNGETC(c); r = skip(" \t"); c = GETC(); if(c == '\n'){ if(debug) fprint(2, "%s\n", ty(Tbreak)); return Tbreak; } UNGETC(c); nblock = r; setstate(Body1); goto genblock; case Body1: /* indent [cmd] inline */ switch(c = GETC()){ case Beof: yyerror("eof in body"); if(debug) fprint(2, "%s\n", ty(Terror)); return fail(Body3); case '=': case '\\': case '+': case '*': case ':': case '-': case '>': if(debug) fprint(2, "%c\n", c); setstate(Body2); return c; case '!': if(debug) fprint(2, "%c\n", c); setstate(Code); return c; case '{': case '}': if(debug) fprint(2, "%c\n", c); setstate(Body3); return c; case '#': if(debug) fprint(2, "%c\n", c); setstate(ID); return c; case '.': if(debug) fprint(2, "%c\n", c); setstate(Class); return c; case '|': if(debug) fprint(2, "%c\n", c); setstate(Table); return c; default: UNGETC(c); if(debug) fprint(2, "\\\n"); setstate(Body2); return '\\'; } case Body2: /* indent cmd [inline] */ case Table: r = skip(" \t"); if(state == Table && r > 0) return ','; switch(c = getcc(&c1, "*[]|<>")){ case Beof: yyerror("eof in body"); if(debug) fprint(2, "%s\n", ty(Terror)); return fail(Body3); case '\n': UNGETC(c); setstate(Body3); break; case '*': case '[': case ']': case '|': case '<': case '>': if(c == '[' || c == '|' || c == '<') skip(" \t\n"); if(debug) fprint(2, "%c\n", c); return c; default: s_reset(sbuf); s_putc(sbuf, c1); while((c=getcc(&c1, "*[]|<>")) == 0){ if(state == Table && c1 == '\t'){ UNGETC(c); break; } s_putc(sbuf, c1); } s_terminate(sbuf); if(c > 0) UNGETC(c); yylval.s = estrdup(s_to_c(sbuf)); if(debug) fprint(2, "%s %q\n", ty(Tstring), yylval.s); return Tstring; } case Body3: skip(" \t"); c = GETC(); if(c != '\n') return fail(Body3); setstate(Body0); return ';'; case Code: r = readstr("\n", "", 1); if(r == Terror){ if(debug) fprint(2, "%s\n", ty(Terror)); return fail(Body3); } setstate(Body3); yylval.s = estrdup(s_to_c(sbuf)); if(debug) fprint(2, "%s %q\n", ty(Tstring), yylval.s); return Tstring; case ID: case Class: r = readname(" \t"); if(r == Terror){ if(debug) fprint(2, "%s\n", ty(Terror)); return fail(Body3); } setstate(Body3); yylval.s = estrdup(s_to_c(sbuf)); if(debug) fprint(2, "%s %q\n", ty(Tstring), yylval.s); return Tstring; default: assert(0); return Terror; } }
/* Loop through the entries in a translation file looking for a match. * Return 0 if found, -1 otherwise. */ static int lookup( String **namev, String *file, String *alias) /* returned String */ { String *line = s_new(); String *token = s_new(); String *bangtoken; int i, rv = -1; char *name = s_to_c(namev[0]); Sinstack *sp; DEBUG print("lookup(%s, %s, %s, %s)\n", s_to_c(namev[0]), s_to_c(namev[1]), s_to_c(file), s_to_c(alias)); s_reset(alias); if ((sp = s_allocinstack(s_to_c(file))) == 0) return -1; /* look for a match */ while (s_rdinstack(sp, s_restart(line))!=0) { DEBUG print("line is %s\n", s_to_c(line)); s_restart(token); if (s_parse(s_restart(line), token)==0) continue; if (compare(token, "#include")==0){ if(s_parse(line, s_restart(token))!=0) { if(lookup(namev, line, alias) == 0) break; } continue; } if (compare(token, name)!=0) continue; /* match found, get the alias */ while(s_parse(line, s_restart(token))!=0) { bangtoken = attobang(token); /* avoid definition loops */ for(i = 0; namev[i]; i++) if(compare(bangtoken, s_to_c(namev[i]))==0) { s_append(alias, "local"); s_append(alias, "!"); s_append(alias, name); break; } if(namev[i] == 0) s_append(alias, s_to_c(token)); s_append(alias, "\n"); if(bangtoken != token) s_free(bangtoken); } rv = 0; break; } s_free(line); s_free(token); s_freeinstack(sp); return rv; }
/** Update the screen to match the desired output. */ static void s_update(screen_t *scr, const wchar_t *left_prompt, const wchar_t *right_prompt) { //if (test_stuff(scr)) return; const size_t left_prompt_width = calc_prompt_layout(left_prompt).last_line_width; const size_t right_prompt_width = calc_prompt_layout(right_prompt).last_line_width; int screen_width = common_get_width(); /* Figure out how many following lines we need to clear (probably 0) */ size_t actual_lines_before_reset = scr->actual_lines_before_reset; scr->actual_lines_before_reset = 0; data_buffer_t output; bool need_clear_lines = scr->need_clear_lines; bool need_clear_screen = scr->need_clear_screen; bool has_cleared_screen = false; if (scr->actual_width != screen_width) { /* Ensure we don't issue a clear screen for the very first output, to avoid https://github.com/fish-shell/fish-shell/issues/402 */ if (scr->actual_width != SCREEN_WIDTH_UNINITIALIZED) { need_clear_screen = true; s_move(scr, &output, 0, 0); s_reset(scr, screen_reset_current_line_contents); need_clear_lines = need_clear_lines || scr->need_clear_lines; need_clear_screen = need_clear_screen || scr->need_clear_screen; } scr->actual_width = screen_width; } scr->need_clear_lines = false; scr->need_clear_screen = false; /* Determine how many lines have stuff on them; we need to clear lines with stuff that we don't want */ const size_t lines_with_stuff = maxi(actual_lines_before_reset, scr->actual.line_count()); if (lines_with_stuff > scr->desired.line_count()) { /* There are lines that we output to previously that will need to be cleared */ //need_clear_lines = true; } if (wcscmp(left_prompt, scr->actual_left_prompt.c_str())) { s_move(scr, &output, 0, 0); s_write_str(&output, left_prompt); scr->actual_left_prompt = left_prompt; scr->actual.cursor.x = (int)left_prompt_width; } for (size_t i=0; i < scr->desired.line_count(); i++) { const line_t &o_line = scr->desired.line(i); line_t &s_line = scr->actual.create_line(i); size_t start_pos = (i==0 ? left_prompt_width : 0); int current_width = 0; /* If this is the last line, maybe we should clear the screen */ const bool should_clear_screen_this_line = (need_clear_screen && i + 1 == scr->desired.line_count() && clr_eos != NULL); /* Note that skip_remaining is a width, not a character count */ size_t skip_remaining = start_pos; if (! should_clear_screen_this_line) { /* Compute how much we should skip. At a minimum we skip over the prompt. But also skip over the shared prefix of what we want to output now, and what we output before, to avoid repeatedly outputting it. */ const size_t shared_prefix = line_shared_prefix(o_line, s_line); if (shared_prefix > 0) { int prefix_width = fish_wcswidth(&o_line.text.at(0), shared_prefix); if (prefix_width > skip_remaining) skip_remaining = prefix_width; } /* If we're soft wrapped, and if we're going to change the first character of the next line, don't skip over the last two characters so that we maintain soft-wrapping */ if (o_line.is_soft_wrapped && i + 1 < scr->desired.line_count()) { bool first_character_of_next_line_will_change = true; if (i + 1 < scr->actual.line_count()) { if (line_shared_prefix(scr->desired.line(i+1), scr->actual.line(i+1)) > 0) { first_character_of_next_line_will_change = false; } } if (first_character_of_next_line_will_change) { skip_remaining = mini(skip_remaining, (size_t)(scr->actual_width - 2)); } } } /* Skip over skip_remaining width worth of characters */ size_t j = 0; for (; j < o_line.size(); j++) { int width = fish_wcwidth_min_0(o_line.char_at(j)); if (skip_remaining < width) break; skip_remaining -= width; current_width += width; } /* Skip over zero-width characters (e.g. combining marks at the end of the prompt) */ for (; j < o_line.size(); j++) { int width = fish_wcwidth_min_0(o_line.char_at(j)); if (width > 0) break; } /* Now actually output stuff */ for (; j < o_line.size(); j++) { /* If we are about to output into the last column, clear the screen first. If we clear the screen after we output into the last column, it can erase the last character due to the sticky right cursor. If we clear the screen too early, we can defeat soft wrapping. */ if (j + 1 == screen_width && should_clear_screen_this_line && ! has_cleared_screen) { s_move(scr, &output, current_width, (int)i); s_write_mbs(&output, clr_eos); has_cleared_screen = true; } perform_any_impending_soft_wrap(scr, current_width, (int)i); s_move(scr, &output, current_width, (int)i); s_set_color(scr, &output, o_line.color_at(j)); s_write_char(scr, &output, o_line.char_at(j)); current_width += fish_wcwidth_min_0(o_line.char_at(j)); } /* Clear the screen if we have not done so yet. */ if (should_clear_screen_this_line && ! has_cleared_screen) { s_move(scr, &output, current_width, (int)i); s_write_mbs(&output, clr_eos); has_cleared_screen = true; } bool clear_remainder = false; /* Clear the remainder of the line if we need to clear and if we didn't write to the end of the line. If we did write to the end of the line, the "sticky right edge" (as part of auto_right_margin) means that we'll be clearing the last character we wrote! */ if (has_cleared_screen) { /* Already cleared everything */ clear_remainder = false; } else if (need_clear_lines && current_width < screen_width) { clear_remainder = true; } else if (right_prompt_width < scr->last_right_prompt_width) { clear_remainder = true; } else { int prev_width = (s_line.text.empty() ? 0 : fish_wcswidth(&s_line.text.at(0), s_line.text.size())); clear_remainder = prev_width > current_width; } if (clear_remainder) { s_set_color(scr, &output, 0xffffffff); s_move(scr, &output, current_width, (int)i); s_write_mbs(&output, clr_eol); } /* Output any rprompt if this is the first line. */ if (i == 0 && right_prompt_width > 0) { s_move(scr, &output, (int)(screen_width - right_prompt_width), (int)i); s_set_color(scr, &output, 0xffffffff); s_write_str(&output, right_prompt); scr->actual.cursor.x += right_prompt_width; /* We output in the last column. Some terms (Linux) push the cursor further right, past the window. Others make it "stick." Since we don't really know which is which, issue a cr so it goes back to the left. However, if the user is resizing the window smaller, then it's possible the cursor wrapped. If so, then a cr will go to the beginning of the following line! So instead issue a bunch of "move left" commands to get back onto the line, and then jump to the front of it (!) */ s_move(scr, &output, scr->actual.cursor.x - (int)right_prompt_width, scr->actual.cursor.y); s_write_str(&output, L"\r"); scr->actual.cursor.x = 0; } } /* Clear remaining lines (if any) if we haven't cleared the screen. */ if (! has_cleared_screen && scr->desired.line_count() < lines_with_stuff) { s_set_color(scr, &output, 0xffffffff); for (size_t i=scr->desired.line_count(); i < lines_with_stuff; i++) { s_move(scr, &output, 0, (int)i); s_write_mbs(&output, clr_eol); } } s_move(scr, &output, scr->desired.cursor.x, scr->desired.cursor.y); s_set_color(scr, &output, 0xffffffff); if (! output.empty()) { write_loop(1, &output.at(0), output.size()); } /* We have now synced our actual screen against our desired screen. Note that this is a big assignment! */ scr->actual = scr->desired; scr->last_right_prompt_width = right_prompt_width; }
/* * find out about the other side. go to it's root if requested. set * image mode if a Plan9 system. */ void preamble(char *mountroot) { char *p, *ep; int rv; OS *o; /* * create a root directory mirror */ remroot = newnode(0, s_copy("/")); remroot->d->qid.type = QTDIR; remroot->d->mode = DMDIR|0777; remdir = remroot; /* * get system type */ sendrequest("SYST", nil); switch(getreply(&ctlin, msg, sizeof(msg), 1)){ case Success: for(o = oslist; o->os != Unknown; o++) if(strncmp(msg+4, o->name, strlen(o->name)) == 0) break; os = o->os; if(os == NT) os = Unix; break; default: os = defos; break; } if(os == Unknown) os = defos; remrootpath = s_reset(remrootpath); switch(os){ case NetWare: /* * Request long, rather than 8.3 filenames, * where the Servers & Volume support them. */ sendrequest("SITE LONG", nil); getreply(&ctlin, msg, sizeof(msg), 0); /* FALL THRU */ case Unix: case Plan9: /* * go to the remote root, if asked */ if(mountroot){ sendrequest("CWD", mountroot); getreply(&ctlin, msg, sizeof(msg), 0); } else { s_append(remrootpath, "/usr/"); s_append(remrootpath, user); } /* * get the root directory */ sendrequest("PWD", nil); rv = getreply(&ctlin, msg, sizeof(msg), 1); if(rv == PermFail){ sendrequest("XPWD", nil); rv = getreply(&ctlin, msg, sizeof(msg), 1); } if(rv == Success){ p = strchr(msg, '"'); if(p){ p++; ep = strchr(p, '"'); if(ep){ *ep = 0; s_append(s_reset(remrootpath), p); } } } break; case Tops: case VM: /* * top directory is a figment of our imagination. * make it permanently cached & valid. */ CACHED(remroot); VALID(remroot); remroot->d->atime = time(0) + 100000; /* * no initial directory. We are in the * imaginary root. */ remdir = newtopsdir("???"); topsdir[0] = 0; if(os == Tops && readdir(remdir) >= 0){ CACHED(remdir); if(*topsdir) remdir->remname = s_copy(topsdir); VALID(remdir); } break; case VMS: /* * top directory is a figment of our imagination. * make it permanently cached & valid. */ CACHED(remroot); VALID(remroot); remroot->d->atime = time(0) + 100000; /* * get current directory */ sendrequest("PWD", nil); rv = getreply(&ctlin, msg, sizeof(msg), 1); if(rv == PermFail){ sendrequest("XPWD", nil); rv = getreply(&ctlin, msg, sizeof(msg), 1); } if(rv == Success){ p = strchr(msg, '"'); if(p){ p++; ep = strchr(p, '"'); if(ep){ *ep = 0; remroot = remdir = vmsdir(p); } } } break; case MVS: usenlst = 1; break; } if(os == Plan9) image(); }
/* * pipe message to mailer with the following transformations: * - change \r\n into \n. * - add sender's domain to any addrs with no domain * - add a From: if none of From:, Sender:, or Replyto: exists * - add a Received: line */ int pipemsg(int *byteswritten) { int n, nbytes, sawdot, status, nonhdr, bpr; char *cp; Field *f; Link *l; Node *p; String *hdr, *line; pipesig(&status); /* set status to 1 on write to closed pipe */ sawdot = 0; status = 0; /* * add a 'From ' line as envelope */ nbytes = 0; nbytes += Bprint(pp->std[0]->fp, "From %s %s remote from \n", s_to_c(senders.first->p), thedate()); /* * add our own Received: stamp */ nbytes += Bprint(pp->std[0]->fp, "Received: from %s ", him); if(nci->rsys) nbytes += Bprint(pp->std[0]->fp, "([%s]) ", nci->rsys); nbytes += Bprint(pp->std[0]->fp, "by %s; %s\n", me, thedate()); /* * read first 16k obeying '.' escape. we're assuming * the header will all be there. */ line = s_new(); hdr = s_new(); while(sawdot == 0 && s_len(hdr) < 16*1024){ n = getcrnl(s_reset(line), &bin); /* eof or error ends the message */ if(n <= 0) break; /* a line with only a '.' ends the message */ cp = s_to_c(line); if(n == 2 && *cp == '.' && *(cp+1) == '\n'){ sawdot = 1; break; } s_append(hdr, *cp == '.' ? cp+1 : cp); } /* * parse header */ yyinit(s_to_c(hdr), s_len(hdr)); yyparse(); /* * Look for masquerades. Let Sender: trump From: to allow mailing list * forwarded messages. */ if(fflag) nbytes += forgedheaderwarnings(); /* * add an orginator and/or destination if either is missing */ if(originator == 0){ if(senders.last == nil || senders.last->p == nil) nbytes += Bprint(pp->std[0]->fp, "From: /dev/null@%s\n", him); else nbytes += Bprint(pp->std[0]->fp, "From: %s\n", s_to_c(senders.last->p)); } if(destination == 0){ nbytes += Bprint(pp->std[0]->fp, "To: "); for(l = rcvers.first; l; l = l->next){ if(l != rcvers.first) nbytes += Bprint(pp->std[0]->fp, ", "); nbytes += Bprint(pp->std[0]->fp, "%s", s_to_c(l->p)); } nbytes += Bprint(pp->std[0]->fp, "\n"); } /* * add sender's domain to any domainless addresses * (to avoid forging local addresses) */ cp = s_to_c(hdr); for(f = firstfield; cp != nil && f; f = f->next){ for(p = f->node; cp != 0 && p; p = p->next) { bpr = 0; cp = bprintnode(pp->std[0]->fp, p, &bpr); nbytes += bpr; } if(status == 0 && Bprint(pp->std[0]->fp, "\n") < 0){ piperror = "write error"; status = 1; } nbytes++; /* for newline */ } if(cp == nil){ piperror = "sender domain"; status = 1; } /* write anything we read following the header */ nonhdr = s_to_c(hdr) + s_len(hdr) - cp; if(status == 0 && Bwrite(pp->std[0]->fp, cp, nonhdr) < 0){ piperror = "write error 2"; status = 1; } nbytes += nonhdr; s_free(hdr); /* * pass rest of message to mailer. take care of '.' * escapes. */ while(sawdot == 0){ n = getcrnl(s_reset(line), &bin); /* eof or error ends the message */ if(n <= 0) break; /* a line with only a '.' ends the message */ cp = s_to_c(line); if(n == 2 && *cp == '.' && *(cp+1) == '\n'){ sawdot = 1; break; } if(cp[0] == '.'){ cp++; n--; } nbytes += n; if(status == 0 && Bwrite(pp->std[0]->fp, cp, n) < 0){ piperror = "write error 3"; status = 1; } } s_free(line); if(sawdot == 0){ /* message did not terminate normally */ snprint(pipbuf, sizeof pipbuf, "network eof: %r"); piperror = pipbuf; if (pp->pid > 0) { syskillpg(pp->pid); /* none can't syskillpg, so try a variant */ sleep(500); syskill(pp->pid); } status = 1; } if(status == 0 && Bflush(pp->std[0]->fp) < 0){ piperror = "write error 4"; status = 1; } if (debug) { stamp(); fprint(2, "at end of message; %s .\n", (sawdot? "saw": "didn't see")); } stream_free(pp->std[0]); pp->std[0] = 0; *byteswritten = nbytes; pipesigoff(); if(status && !piperror) piperror = "write on closed pipe"; return status; }
RD_BOOL cssp_connect(char *server, char *user, char *domain, char *password, STREAM s) { OM_uint32 actual_time; gss_cred_id_t cred; gss_buffer_desc input_tok, output_tok; gss_name_t target_name; OM_uint32 major_status, minor_status; int context_established = 0; gss_ctx_id_t gss_ctx; gss_OID desired_mech = &_gss_spnego_krb5_mechanism_oid_desc; STREAM ts_creds; struct stream token = { 0 }; struct stream pubkey = { 0 }; struct stream pubkey_cmp = { 0 }; // Verify that system gss support spnego if (!cssp_gss_mech_available(desired_mech)) { warning("CredSSP: System doesn't have support for desired authentication mechanism.\n"); return False; } // Get service name if (!cssp_gss_get_service_name(server, &target_name)) { warning("CredSSP: Failed to get target service name.\n"); return False; } // Establish tls connection to server if (!tcp_tls_connect()) { warning("CredSSP: Failed to establish TLS connection.\n"); return False; } tcp_tls_get_server_pubkey(&pubkey); #ifdef WITH_DEBUG_CREDSSP streamsave(&pubkey, "PubKey.raw"); #endif // Enter the spnego loop OM_uint32 actual_services; gss_OID actual_mech; struct stream blob = { 0 }; gss_ctx = GSS_C_NO_CONTEXT; cred = GSS_C_NO_CREDENTIAL; input_tok.length = 0; output_tok.length = 0; minor_status = 0; int i = 0; do { major_status = gss_init_sec_context(&minor_status, cred, &gss_ctx, target_name, desired_mech, GSS_C_MUTUAL_FLAG | GSS_C_DELEG_FLAG, GSS_C_INDEFINITE, GSS_C_NO_CHANNEL_BINDINGS, &input_tok, &actual_mech, &output_tok, &actual_services, &actual_time); if (GSS_ERROR(major_status)) { if (i == 0) error("CredSSP: Initialize failed, do you have correct kerberos tgt initialized ?\n"); else error("CredSSP: Negotiation failed.\n"); #ifdef WITH_DEBUG_CREDSSP cssp_gss_report_error(GSS_C_GSS_CODE, "CredSSP: SPNEGO negotiation failed.", major_status, minor_status); #endif goto bail_out; } // validate required services if (!(actual_services & GSS_C_CONF_FLAG)) { error("CredSSP: Confidiality service required but is not available.\n"); goto bail_out; } // Send token to server if (output_tok.length != 0) { if (output_tok.length > token.size) s_realloc(&token, output_tok.length); s_reset(&token); out_uint8p(&token, output_tok.value, output_tok.length); s_mark_end(&token); if (!cssp_send_tsrequest(&token, NULL, NULL)) goto bail_out; (void) gss_release_buffer(&minor_status, &output_tok); } // Read token from server if (major_status & GSS_S_CONTINUE_NEEDED) { (void) gss_release_buffer(&minor_status, &input_tok); if (!cssp_read_tsrequest(&token, NULL)) goto bail_out; input_tok.value = token.data; input_tok.length = s_length(&token); } else { // Send encrypted pubkey for verification to server context_established = 1; if (!cssp_gss_wrap(gss_ctx, &pubkey, &blob)) goto bail_out; if (!cssp_send_tsrequest(NULL, NULL, &blob)) goto bail_out; context_established = 1; } i++; } while (!context_established); // read tsrequest response and decrypt for public key validation if (!cssp_read_tsrequest(NULL, &blob)) goto bail_out; if (!cssp_gss_unwrap(gss_ctx, &blob, &pubkey_cmp)) goto bail_out; pubkey_cmp.data[0] -= 1; // validate public key if (memcmp(pubkey.data, pubkey_cmp.data, s_length(&pubkey)) != 0) { error("CredSSP: Cannot guarantee integrity of server connection, MITM ? " "(public key data mismatch)\n"); goto bail_out; } // Send TSCredentials ts_creds = cssp_encode_tscredentials(user, password, domain); if (!cssp_gss_wrap(gss_ctx, ts_creds, &blob)) goto bail_out; s_free(ts_creds); if (!cssp_send_tsrequest(NULL, &blob, NULL)) goto bail_out; return True; bail_out: xfree(token.data); return False; }
RD_BOOL cssp_send_tsrequest(STREAM token, STREAM auth, STREAM pubkey) { STREAM s; STREAM h1, h2, h3, h4, h5; struct stream tmp = { 0 }; struct stream message = { 0 }; memset(&message, 0, sizeof(message)); memset(&tmp, 0, sizeof(tmp)); // version [0] s_realloc(&tmp, sizeof(uint8)); s_reset(&tmp); out_uint8(&tmp, 2); s_mark_end(&tmp); h2 = ber_wrap_hdr_data(BER_TAG_INTEGER, &tmp); h1 = ber_wrap_hdr_data(BER_TAG_CTXT_SPECIFIC | BER_TAG_CONSTRUCTED | 0, h2); s_realloc(&message, s_length(&message) + s_length(h1)); out_uint8p(&message, h1->data, s_length(h1)); s_mark_end(&message); s_free(h2); s_free(h1); // negoToken [1] if (token && s_length(token)) { h5 = ber_wrap_hdr_data(BER_TAG_OCTET_STRING, token); h4 = ber_wrap_hdr_data(BER_TAG_CTXT_SPECIFIC | BER_TAG_CONSTRUCTED | 0, h5); h3 = ber_wrap_hdr_data(BER_TAG_SEQUENCE | BER_TAG_CONSTRUCTED, h4); h2 = ber_wrap_hdr_data(BER_TAG_SEQUENCE | BER_TAG_CONSTRUCTED, h3); h1 = ber_wrap_hdr_data(BER_TAG_CTXT_SPECIFIC | BER_TAG_CONSTRUCTED | 1, h2); s_realloc(&message, s_length(&message) + s_length(h1)); out_uint8p(&message, h1->data, s_length(h1)); s_mark_end(&message); s_free(h5); s_free(h4); s_free(h3); s_free(h2); s_free(h1); } // authInfo [2] if (auth && s_length(auth)) { h2 = ber_wrap_hdr_data(BER_TAG_OCTET_STRING, auth); h1 = ber_wrap_hdr_data(BER_TAG_CTXT_SPECIFIC | BER_TAG_CONSTRUCTED | 2, h2); s_realloc(&message, s_length(&message) + s_length(h1)); out_uint8p(&message, h1->data, s_length(h1)); s_free(h2); s_free(h1); } // pubKeyAuth [3] if (pubkey && s_length(pubkey)) { h2 = ber_wrap_hdr_data(BER_TAG_OCTET_STRING, pubkey); h1 = ber_wrap_hdr_data(BER_TAG_CTXT_SPECIFIC | BER_TAG_CONSTRUCTED | 3, h2); s_realloc(&message, s_length(&message) + s_length(h1)); out_uint8p(&message, h1->data, s_length(h1)); s_mark_end(&message); s_free(h2); s_free(h1); } s_mark_end(&message); // Construct ASN.1 Message // Todo: can h1 be send directly instead of tcp_init() approach h1 = ber_wrap_hdr_data(BER_TAG_SEQUENCE | BER_TAG_CONSTRUCTED, &message); s = tcp_init(s_length(h1)); out_uint8p(s, h1->data, s_length(h1)); s_mark_end(s); s_free(h1); #if WITH_DEBUG_CREDSSP streamsave(s, "tsrequest_out.raw"); printf("Out TSRequest %ld bytes\n", s_length(s)); hexdump(s->data, s_length(s)); #endif tcp_send(s); // cleanup xfree(message.data); xfree(tmp.data); return True; }
STREAM cssp_encode_tscredentials(char *username, char *password, char *domain) { STREAM out; STREAM h1, h2, h3; struct stream tmp = { 0 }; struct stream message = { 0 }; // credType [0] s_realloc(&tmp, sizeof(uint8)); s_reset(&tmp); if (g_use_password_as_pin == False) { out_uint8(&tmp, 1); // TSPasswordCreds } else { out_uint8(&tmp, 2); // TSSmartCardCreds } s_mark_end(&tmp); h2 = ber_wrap_hdr_data(BER_TAG_INTEGER, &tmp); h1 = ber_wrap_hdr_data(BER_TAG_CTXT_SPECIFIC | BER_TAG_CONSTRUCTED | 0, h2); s_realloc(&message, s_length(&message) + s_length(h1)); out_uint8p(&message, h1->data, s_length(h1)); s_mark_end(&message); s_free(h2); s_free(h1); // credentials [1] if (g_use_password_as_pin == False) { h3 = cssp_encode_tspasswordcreds(username, password, domain); } else { h3 = cssp_encode_tssmartcardcreds(username, password, domain); } h2 = ber_wrap_hdr_data(BER_TAG_OCTET_STRING, h3); h1 = ber_wrap_hdr_data(BER_TAG_CTXT_SPECIFIC | BER_TAG_CONSTRUCTED | 1, h2); s_realloc(&message, s_length(&message) + s_length(h1)); out_uint8p(&message, h1->data, s_length(h1)); s_mark_end(&message); s_free(h3); s_free(h2); s_free(h1); // Construct ASN.1 message out = ber_wrap_hdr_data(BER_TAG_SEQUENCE | BER_TAG_CONSTRUCTED, &message); #if WITH_DEBUG_CREDSSP streamsave(out, "tscredentials.raw"); printf("Out TSCredentials %ld bytes\n", s_length(out)); hexdump(out->data, s_length(out)); #endif // cleanup xfree(message.data); xfree(tmp.data); return out; }
static STREAM cssp_encode_tssmartcardcreds(char *username, char *password, char *domain) { STREAM out, h1, h2; struct stream tmp = { 0 }; struct stream message = { 0 }; // pin [0] s_realloc(&tmp, strlen(password) * sizeof(uint16)); s_reset(&tmp); rdp_out_unistr(&tmp, password, strlen(password) * sizeof(uint16)); s_mark_end(&tmp); h2 = ber_wrap_hdr_data(BER_TAG_OCTET_STRING, &tmp); h1 = ber_wrap_hdr_data(BER_TAG_CTXT_SPECIFIC | BER_TAG_CONSTRUCTED | 0, h2); s_realloc(&message, s_length(&message) + s_length(h1)); out_uint8p(&message, h1->data, s_length(h1)); s_mark_end(&message); s_free(h2); s_free(h1); // cspData[1] h2 = cssp_encode_tscspdatadetail(AT_KEYEXCHANGE, g_sc_card_name, g_sc_reader_name, g_sc_container_name, g_sc_csp_name); h1 = ber_wrap_hdr_data(BER_TAG_CTXT_SPECIFIC | BER_TAG_CONSTRUCTED | 1, h2); s_realloc(&message, s_length(&message) + s_length(h1)); out_uint8p(&message, h1->data, s_length(h1)); s_mark_end(&message); s_free(h2); s_free(h1); // userHint [2] if (username && strlen(username)) { s_realloc(&tmp, strlen(username) * sizeof(uint16)); s_reset(&tmp); rdp_out_unistr(&tmp, username, strlen(username) * sizeof(uint16)); s_mark_end(&tmp); h2 = ber_wrap_hdr_data(BER_TAG_OCTET_STRING, &tmp); h1 = ber_wrap_hdr_data(BER_TAG_CTXT_SPECIFIC | BER_TAG_CONSTRUCTED | 2, h2); s_realloc(&message, s_length(&message) + s_length(h1)); out_uint8p(&message, h1->data, s_length(h1)); s_mark_end(&message); s_free(h2); s_free(h1); } // domainHint [3] if (domain && strlen(domain)) { s_realloc(&tmp, strlen(domain) * sizeof(uint16)); s_reset(&tmp); rdp_out_unistr(&tmp, domain, strlen(domain) * sizeof(uint16)); s_mark_end(&tmp); h2 = ber_wrap_hdr_data(BER_TAG_OCTET_STRING, &tmp); h1 = ber_wrap_hdr_data(BER_TAG_CTXT_SPECIFIC | BER_TAG_CONSTRUCTED | 3, h2); s_realloc(&message, s_length(&message) + s_length(h1)); out_uint8p(&message, h1->data, s_length(h1)); s_mark_end(&message); s_free(h2); s_free(h1); } s_mark_end(&message); // build message out = ber_wrap_hdr_data(BER_TAG_SEQUENCE | BER_TAG_CONSTRUCTED, &message); // cleanup free(tmp.data); free(message.data); return out; }
static STREAM cssp_encode_tscspdatadetail(unsigned char keyspec, char *card, char *reader, char *container, char *csp) { STREAM out; STREAM h1, h2; struct stream tmp = { 0 }; struct stream message = { 0 }; // keySpec [0] s_realloc(&tmp, sizeof(uint8)); s_reset(&tmp); out_uint8(&tmp, keyspec); s_mark_end(&tmp); h2 = ber_wrap_hdr_data(BER_TAG_INTEGER, &tmp); h1 = ber_wrap_hdr_data(BER_TAG_CTXT_SPECIFIC | BER_TAG_CONSTRUCTED | 0, h2); s_realloc(&message, s_length(&message) + s_length(h1)); out_uint8p(&message, h1->data, s_length(h1)); s_mark_end(&message); s_free(h2); s_free(h1); // cardName [1] if (card) { s_realloc(&tmp, 4 + strlen(card) * sizeof(uint16)); s_reset(&tmp); rdp_out_unistr(&tmp, card, strlen(card) * sizeof(uint16)); s_mark_end(&tmp); h2 = ber_wrap_hdr_data(BER_TAG_OCTET_STRING, &tmp); h1 = ber_wrap_hdr_data(BER_TAG_CTXT_SPECIFIC | BER_TAG_CONSTRUCTED | 1, h2); s_realloc(&message, s_length(&message) + s_length(h1)); out_uint8p(&message, h1->data, s_length(h1)); s_mark_end(&message); s_free(h2); s_free(h1); } // readerName [2] if (reader) { s_realloc(&tmp, 4 + strlen(reader) * sizeof(uint16)); s_reset(&tmp); rdp_out_unistr(&tmp, reader, strlen(reader) * sizeof(uint16)); s_mark_end(&tmp); h2 = ber_wrap_hdr_data(BER_TAG_OCTET_STRING, &tmp); h1 = ber_wrap_hdr_data(BER_TAG_CTXT_SPECIFIC | BER_TAG_CONSTRUCTED | 2, h2); s_realloc(&message, s_length(&message) + s_length(h1)); out_uint8p(&message, h1->data, s_length(h1)); s_mark_end(&message); s_free(h2); s_free(h1); } // containerName [3] if (container) { s_realloc(&tmp, 4 + strlen(container) * sizeof(uint16)); s_reset(&tmp); rdp_out_unistr(&tmp, container, strlen(container) * sizeof(uint16)); s_mark_end(&tmp); h2 = ber_wrap_hdr_data(BER_TAG_OCTET_STRING, &tmp); h1 = ber_wrap_hdr_data(BER_TAG_CTXT_SPECIFIC | BER_TAG_CONSTRUCTED | 3, h2); s_realloc(&message, s_length(&message) + s_length(h1)); out_uint8p(&message, h1->data, s_length(h1)); s_mark_end(&message); s_free(h2); s_free(h1); } // cspName [4] if (csp) { s_realloc(&tmp, 4 + strlen(csp) * sizeof(uint16)); s_reset(&tmp); rdp_out_unistr(&tmp, csp, strlen(csp) * sizeof(uint16)); s_mark_end(&tmp); h2 = ber_wrap_hdr_data(BER_TAG_OCTET_STRING, &tmp); h1 = ber_wrap_hdr_data(BER_TAG_CTXT_SPECIFIC | BER_TAG_CONSTRUCTED | 4, h2); s_realloc(&message, s_length(&message) + s_length(h1)); out_uint8p(&message, h1->data, s_length(h1)); s_mark_end(&message); s_free(h2); s_free(h1); } s_mark_end(&message); // build message out = ber_wrap_hdr_data(BER_TAG_SEQUENCE | BER_TAG_CONSTRUCTED, &message); // cleanup free(tmp.data); free(message.data); return out; }
/** Update the screen to match the desired output. */ static void s_update( screen_t *scr, const wchar_t *prompt ) { size_t prompt_width = calc_prompt_width( prompt ); int screen_width = common_get_width(); int need_clear = scr->need_clear; data_buffer_t output; scr->need_clear = 0; if( scr->actual_width != screen_width ) { need_clear = 1; s_move( scr, &output, 0, 0 ); scr->actual_width = screen_width; s_reset( scr, false ); } if( wcscmp( prompt, scr->actual_prompt.c_str() ) ) { s_move( scr, &output, 0, 0 ); s_write_str( &output, prompt ); scr->actual_prompt = prompt; scr->actual.cursor.x = (int)prompt_width; } for (size_t i=0; i < scr->desired.line_count(); i++) { const line_t &o_line = scr->desired.line(i); line_t &s_line = scr->actual.create_line(i); size_t start_pos = (i==0 ? prompt_width : 0); int current_width = 0; if( need_clear ) { s_move( scr, &output, (int)start_pos, (int)i ); s_write_mbs( &output, clr_eol); s_line.clear(); } /* Note that skip_remaining is a width, not a character count */ size_t skip_remaining = start_pos; /* Compute how much we should skip. At a minimum we skip over the prompt. But also skip over the shared prefix of what we want to output now, and what we output before, to avoid repeatedly outputting it. */ size_t shared_prefix = line_shared_prefix(o_line, s_line); if (shared_prefix > 0) { int prefix_width = fish_wcswidth(&o_line.text.at(0), shared_prefix); if (prefix_width > skip_remaining) skip_remaining = prefix_width; } /* Skip over skip_remaining width worth of characters */ size_t j = 0; for ( ; j < o_line.size(); j++) { int width = fish_wcwidth(o_line.char_at(j)); if (skip_remaining <= width) break; skip_remaining -= width; current_width += width; } /* Skip over zero-width characters (e.g. combining marks at the end of the prompt) */ for ( ; j < o_line.size(); j++) { int width = fish_wcwidth(o_line.char_at(j)); if (width > 0) break; } /* Now actually output stuff */ for ( ; j < o_line.size(); j++) { s_move( scr, &output, current_width, (int)i ); s_set_color( scr, &output, o_line.color_at(j) ); s_write_char( scr, &output, o_line.char_at(j) ); current_width += fish_wcwidth(o_line.char_at(j)); } /* If we wrote more on this line last time, clear it */ int prev_length = (s_line.text.empty() ? 0 : fish_wcswidth(&s_line.text.at(0), s_line.text.size())); if (prev_length > current_width ) { s_move( scr, &output, current_width, (int)i ); s_write_mbs( &output, clr_eol); } } /* Clear remaining lines */ for( size_t i=scr->desired.line_count(); i < scr->actual.line_count(); i++ ) { s_move( scr, &output, 0, (int)i ); s_write_mbs( &output, clr_eol); } s_move( scr, &output, scr->desired.cursor.x, scr->desired.cursor.y ); s_set_color( scr, &output, 0xffffffff); if( ! output.empty() ) { write_loop( 1, &output.at(0), output.size() ); } /* We have now synced our actual screen against our desired screen. Note that this is a big assignment! */ scr->actual = scr->desired; }