예제 #1
0
파일: PTY.C 프로젝트: AshKash/kit-sink
static void setup_utmp(char *ttyname, char *location)
{
#ifndef OMIT_UTMP
#ifdef HAVE_LASTLOG
    struct lastlog lastlog_entry;
    FILE *lastlog;
#endif
    struct passwd *pw;
    FILE *wtmp;

    pw = getpwuid(getuid());
    memset(&utmp_entry, 0, sizeof(utmp_entry));
    utmp_entry.ut_type = USER_PROCESS;
    utmp_entry.ut_pid = getpid();
    strncpy(utmp_entry.ut_line, ttyname+5, lenof(utmp_entry.ut_line));
    strncpy(utmp_entry.ut_id, ttyname+8, lenof(utmp_entry.ut_id));
    strncpy(utmp_entry.ut_user, pw->pw_name, lenof(utmp_entry.ut_user));
    strncpy(utmp_entry.ut_host, location, lenof(utmp_entry.ut_host));
    time(&utmp_entry.ut_time);

#if defined HAVE_PUTUTLINE
    utmpname(UTMP_FILE);
    setutent();
    pututline(&utmp_entry);
    endutent();
#endif

    if ((wtmp = fopen(WTMP_FILE, "a")) != NULL) {
	fwrite(&utmp_entry, 1, sizeof(utmp_entry), wtmp);
	fclose(wtmp);
    }

#ifdef HAVE_LASTLOG
    memset(&lastlog_entry, 0, sizeof(lastlog_entry));
    strncpy(lastlog_entry.ll_line, ttyname+5, lenof(lastlog_entry.ll_line));
    strncpy(lastlog_entry.ll_host, location, lenof(lastlog_entry.ll_host));
    time(&lastlog_entry.ll_time);
    if ((lastlog = fopen(LASTLOG_FILE, "r+")) != NULL) {
	fseek(lastlog, sizeof(lastlog_entry) * getuid(), SEEK_SET);
	fwrite(&lastlog_entry, 1, sizeof(lastlog_entry), lastlog);
	fclose(lastlog);
    }
#endif

    pty_stamped_utmp = 1;

#endif
}
예제 #2
0
파일: sftp.c 프로젝트: lalbornoz/FySTY
/*
 * Deal with (and free) an FXP_STATUS packet. Return 1 if
 * SSH_FX_OK, 0 if SSH_FX_EOF, and -1 for anything else (error).
 * Also place the status into fxp_errtype.
 */
static int fxp_got_status(struct sftp_packet *pktin)
{
    static const char *const messages[] = {
	/* SSH_FX_OK. The only time we will display a _message_ for this
	 * is if we were expecting something other than FXP_STATUS on
	 * success, so this is actually an error message! */
	"unexpected OK response",
	"end of file",
	"no such file or directory",
	"permission denied",
	"failure",
	"bad message",
	"no connection",
	"connection lost",
	"operation unsupported",
    };

    if (pktin->type != SSH_FXP_STATUS) {
	fxp_error_message = "expected FXP_STATUS packet";
	fxp_errtype = -1;
    } else {
	fxp_errtype = get_uint32(pktin);
	if (get_err(pktin)) {
	    fxp_error_message = "malformed FXP_STATUS packet";
	    fxp_errtype = -1;
	} else {
	    if (fxp_errtype < 0 || fxp_errtype >= lenof(messages))
		fxp_error_message = "unknown error code";
	    else
		fxp_error_message = messages[fxp_errtype];
	}
    }

    if (fxp_errtype == SSH_FX_OK)
	return 1;
    else if (fxp_errtype == SSH_FX_EOF)
	return 0;
    else
	return -1;
}
예제 #3
0
static void setup_utmp(char *ttyname, char *location)
{
#ifdef HAVE_LASTLOG
    struct lastlog lastlog_entry;
    FILE *lastlog;
#endif
    struct passwd *pw;
    struct timeval tv;

    pw = getpwuid(getuid());
    memset(&utmp_entry, 0, sizeof(utmp_entry));
    utmp_entry.ut_type = USER_PROCESS;
    utmp_entry.ut_pid = getpid();
    strncpy(utmp_entry.ut_line, ttyname+5, lenof(utmp_entry.ut_line));
    strncpy(utmp_entry.ut_id, ttyname+8, lenof(utmp_entry.ut_id));
    strncpy(utmp_entry.ut_user, pw->pw_name, lenof(utmp_entry.ut_user));
    strncpy(utmp_entry.ut_host, location, lenof(utmp_entry.ut_host));
    /*
     * Apparently there are some architectures where (struct
     * utmpx).ut_tv is not essentially struct timeval (e.g. Linux
     * amd64). Hence the temporary.
     */
    gettimeofday(&tv, NULL);
    utmp_entry.ut_tv.tv_sec = tv.tv_sec;
    utmp_entry.ut_tv.tv_usec = tv.tv_usec;

    setutxent();
    pututxline(&utmp_entry);
    endutxent();

    updwtmpx(WTMPX_FILE, &utmp_entry);

#ifdef HAVE_LASTLOG
    memset(&lastlog_entry, 0, sizeof(lastlog_entry));
    strncpy(lastlog_entry.ll_line, ttyname+5, lenof(lastlog_entry.ll_line));
    strncpy(lastlog_entry.ll_host, location, lenof(lastlog_entry.ll_host));
    time(&lastlog_entry.ll_time);
    if ((lastlog = fopen(LASTLOG_FILE, "r+")) != NULL) {
	fseek(lastlog, sizeof(lastlog_entry) * getuid(), SEEK_SET);
	fwrite(&lastlog_entry, 1, sizeof(lastlog_entry), lastlog);
	fclose(lastlog);
    }
#endif

    pty_stamped_utmp = 1;

}
예제 #4
0
static int game_fetch_preset(int i, char **name, game_params **params)
{
    char str[80];
    game_params *ret;

    if (i < 0 || i >= lenof(blackbox_presets))
        return FALSE;

    ret = snew(game_params);
    *ret = blackbox_presets[i];

    if (ret->minballs == ret->maxballs)
        sprintf(str, _("%dx%d, %d balls"),
                ret->w, ret->h, ret->minballs);
    else
        sprintf(str, _("%dx%d, %d-%d balls"),
                ret->w, ret->h, ret->minballs, ret->maxballs);

    *name = dupstr(str);
    *params = ret;
    return TRUE;
}
예제 #5
0
파일: bk_text.c 프로젝트: mloar/halibut
static void text_output(textfile *tf, const wchar_t *s)
{
    char buf[256];
    int ret, len;
    const wchar_t **sp;

    if (!s) {
	sp = NULL;
	len = 1;
    } else {
	sp = &s;
	len = ustrlen(s);
    }

    while (len > 0) {
	ret = charset_from_unicode(sp, &len, buf, lenof(buf),
				   tf->charset, &tf->state, NULL);
	if (!sp)
	    len = 0;
	fwrite(buf, 1, ret, tf->fp);
    }
}
예제 #6
0
/* {{{ void http_ob_etaghandler(char *, uint, char **, uint *, int) */
void _http_ob_etaghandler(char *output, uint output_len,
	char **handled_output, uint *handled_output_len, int mode TSRMLS_DC)
{
	/* passthru */
	*handled_output_len = output_len;
	*handled_output = estrndup(output, output_len);
	
	/* are we supposed to run? */
	if (HTTP_G->etag.started) {
		/* initialize the etag context */
		if (mode & PHP_OUTPUT_HANDLER_START) {
			HTTP_G->etag.ctx = http_etag_init();
		}
		
		/* update */
		http_etag_update(HTTP_G->etag.ctx, output, output_len);
		
		/* finish */
		if (mode & PHP_OUTPUT_HANDLER_END) {
			char *sent_header = NULL;
			char *etag = http_etag_finish(HTTP_G->etag.ctx);
			
			HTTP_G->etag.ctx = NULL;
			
			http_send_cache_control(HTTP_DEFAULT_CACHECONTROL, lenof(HTTP_DEFAULT_CACHECONTROL));
			http_send_etag_ex(etag, strlen(etag), &sent_header);
			
			if (http_match_etag("HTTP_IF_NONE_MATCH", etag)) {
				/* force exit; ob within ob does not work */
				HTTP_G->force_exit = 1;
				http_exit_ex(304, sent_header, etag, 0);
			}
			
			STR_FREE(sent_header);
			STR_FREE(etag);
		}
	}
}
예제 #7
0
static int game_fetch_preset(int i, char **name, game_params **params)
{
    static struct {
        char *title;
        game_params params;
    } presets[] = {
        { "3x3 rows only", { 3, 3, 2, TRUE, FALSE } },
        { "3x3 normal", { 3, 3, 2, FALSE, FALSE } },
        { "3x3 orientable", { 3, 3, 2, FALSE, TRUE } },
        { "4x4 normal", { 4, 4, 2, FALSE } },
        { "4x4 orientable", { 4, 4, 2, FALSE, TRUE } },
        { "4x4, rotating 3x3 blocks", { 4, 4, 3, FALSE } },
        { "5x5, rotating 3x3 blocks", { 5, 5, 3, FALSE } },
        { "6x6, rotating 4x4 blocks", { 6, 6, 4, FALSE } },
    };

    if (i < 0 || i >= lenof(presets))
        return FALSE;

    *name = dupstr(presets[i].title);
    *params = dup_params(&presets[i].params);

    return TRUE;
}
예제 #8
0
파일: cube.c 프로젝트: JetChen07/sgtpuzzles
static char *validate_params(const game_params *params, int full)
{
    int classes[5];
    int i;

    if (params->solid < 0 || params->solid >= lenof(solids))
	return _("Unrecognised solid type");

    if (solids[params->solid]->order == 4) {
	if (params->d1 <= 0 || params->d2 <= 0)
	    return _("Both grid dimensions must be greater than zero");
    } else {
	if (params->d1 <= 0 && params->d2 <= 0)
	    return _("At least one grid dimension must be greater than zero");
    }

    for (i = 0; i < 4; i++)
	classes[i] = 0;
    if (params->solid == TETRAHEDRON)
	classes[4] = 4;
    else if (params->solid == OCTAHEDRON)
	classes[4] = 2;
    else
	classes[4] = 1;
    enum_grid_squares(params, count_grid_square_callback, classes);

    for (i = 0; i < classes[4]; i++)
	if (classes[i] < solids[params->solid]->nfaces / classes[4])
	    return _("Not enough grid space to place all blue faces");

    if (grid_area(params->d1, params->d2, solids[params->solid]->order) <
	solids[params->solid]->nfaces + 1)
	return _("Not enough space to place the solid on an empty square");

    return NULL;
}
예제 #9
0
파일: display.c 프로젝트: DavideD/BizHawk
/**
 * do_buffer_swap:  Perform a display buffer swap (call guSync(), swap the
 * display and work surfaces, wait for the following vertical blank, and
 * calculate the length of time between this newly displayed frame and the
 * previous one).  Called either from the buffer swap thread or (if the
 * swap thread fails to start) from the main thread.
 *
 * [Parameters]
 *     None
 * [Return value]
 *     None
 */
static void do_buffer_swap(void)
{
    guSync(0, 0);
    sceDisplaySetFrameBuf(surfaces[work_surface], DISPLAY_STRIDE,
                          display_mode, PSP_DISPLAY_SETBUF_NEXTFRAME);
    displayed_surface = work_surface;
    work_surface = (work_surface + 1) % lenof(surfaces);
    sceDisplayWaitVblankStart();

    /* Update the frame length variables.  If this is the first frame
     * we've drawn (signaled by last_frame_start == 0), just set a frame
     * length of 1 (1/60 sec) since we have nothing to compare it against. */
    const uint32_t now = sceKernelGetSystemTimeLow();
    const uint32_t last_frame_time = now - last_frame_start;
    const uint32_t time_unit = (1001000+30)/60;
    if (last_frame_start != 0) {
        last_frame_length = (last_frame_time + time_unit/2) / time_unit;
    } else {
        last_frame_length = 1;
    }
    /* Make sure we don't accidentally signal the next frame as the
     * first frame drawn. */
    last_frame_start = (now != 0) ? now : 1;
}
예제 #10
0
파일: LOCALENC.C 프로젝트: BillyWu/putty
int charset_from_localenc(const char *name)
{
    int i;

    if ( (i = charset_from_mimeenc(name)) != CS_NONE)
	return i;
    if ( (i = charset_from_xenc(name)) != CS_NONE)
	return i;

    for (i = 0; i < (int)lenof(localencs); i++) {
	const char *p, *q;
	p = name;
	q = localencs[i].name;
	while (*p || *q) {
		if (tolower((unsigned char)*p) != tolower((unsigned char)*q))
		break;
	    p++; q++;
	}
	if (!*p && !*q)
	    return localencs[i].charset;
    }

    return CS_NONE;		       /* not found */
}
예제 #11
0
파일: settings.c 프로젝트: emonkak/putty
void load_open_settings(void *sesskey, Config *cfg)
{
    int i;
    char prot[10];

    cfg->ssh_subsys = 0;	       /* FIXME: load this properly */
    cfg->remote_cmd_ptr = NULL;
    cfg->remote_cmd_ptr2 = NULL;
    cfg->ssh_nc_host[0] = '\0';

    gpps(sesskey, "HostName", "", cfg->host, sizeof(cfg->host));
    gppfile(sesskey, "LogFileName", &cfg->logfilename);
    gppi(sesskey, "LogType", 0, &cfg->logtype);
    gppi(sesskey, "LogFileClash", LGXF_ASK, &cfg->logxfovr);
    gppi(sesskey, "LogFlush", 1, &cfg->logflush);
    gppi(sesskey, "SSHLogOmitPasswords", 1, &cfg->logomitpass);
    gppi(sesskey, "SSHLogOmitData", 0, &cfg->logomitdata);

    gpps(sesskey, "Protocol", "default", prot, 10);
    cfg->protocol = default_protocol;
    cfg->port = default_port;
    {
	const Backend *b = backend_from_name(prot);
	if (b) {
	    cfg->protocol = b->protocol;
	    gppi(sesskey, "PortNumber", default_port, &cfg->port);
	}
    }

    /* Address family selection */
    gppi(sesskey, "AddressFamily", ADDRTYPE_UNSPEC, &cfg->addressfamily);

    /* The CloseOnExit numbers are arranged in a different order from
     * the standard FORCE_ON / FORCE_OFF / AUTO. */
    gppi(sesskey, "CloseOnExit", 1, &i); cfg->close_on_exit = (i+1)%3;
    gppi(sesskey, "WarnOnClose", 1, &cfg->warn_on_close);
    {
	/* This is two values for backward compatibility with 0.50/0.51 */
	int pingmin, pingsec;
	gppi(sesskey, "PingInterval", 0, &pingmin);
	gppi(sesskey, "PingIntervalSecs", 0, &pingsec);
	cfg->ping_interval = pingmin * 60 + pingsec;
    }
    gppi(sesskey, "TCPNoDelay", 1, &cfg->tcp_nodelay);
    gppi(sesskey, "TCPKeepalives", 0, &cfg->tcp_keepalives);
    gpps(sesskey, "TerminalType", "xterm", cfg->termtype,
	 sizeof(cfg->termtype));
    gpps(sesskey, "TerminalSpeed", "38400,38400", cfg->termspeed,
	 sizeof(cfg->termspeed));
    {
	/* This hardcodes a big set of defaults in any new saved
	 * sessions. Let's hope we don't change our mind. */
	int i;
	char *def = dupstr("");
	/* Default: all set to "auto" */
	for (i = 0; ttymodes[i]; i++) {
	    char *def2 = dupprintf("%s%s=A,", def, ttymodes[i]);
	    sfree(def);
	    def = def2;
	}
	gppmap(sesskey, "TerminalModes", def,
	       cfg->ttymodes, lenof(cfg->ttymodes));
	sfree(def);
    }

    /* proxy settings */
    gpps(sesskey, "ProxyExcludeList", "", cfg->proxy_exclude_list,
	 sizeof(cfg->proxy_exclude_list));
    gppi(sesskey, "ProxyDNS", 1, &i); cfg->proxy_dns = (i+1)%3;
    gppi(sesskey, "ProxyLocalhost", 0, &cfg->even_proxy_localhost);
    gppi(sesskey, "ProxyMethod", -1, &cfg->proxy_type);
    if (cfg->proxy_type == -1) {
        int i;
        gppi(sesskey, "ProxyType", 0, &i);
        if (i == 0)
            cfg->proxy_type = PROXY_NONE;
        else if (i == 1)
            cfg->proxy_type = PROXY_HTTP;
        else if (i == 3)
            cfg->proxy_type = PROXY_TELNET;
        else if (i == 4)
            cfg->proxy_type = PROXY_CMD;
        else {
            gppi(sesskey, "ProxySOCKSVersion", 5, &i);
            if (i == 5)
                cfg->proxy_type = PROXY_SOCKS5;
            else
                cfg->proxy_type = PROXY_SOCKS4;
        }
    }
    gpps(sesskey, "ProxyHost", "proxy", cfg->proxy_host,
	 sizeof(cfg->proxy_host));
    gppi(sesskey, "ProxyPort", 80, &cfg->proxy_port);
    gpps(sesskey, "ProxyUsername", "", cfg->proxy_username,
	 sizeof(cfg->proxy_username));
    gpps(sesskey, "ProxyPassword", "", cfg->proxy_password,
	 sizeof(cfg->proxy_password));
    gpps(sesskey, "ProxyTelnetCommand", "connect %host %port\\n",
	 cfg->proxy_telnet_command, sizeof(cfg->proxy_telnet_command));
    gppmap(sesskey, "Environment", "", cfg->environmt, lenof(cfg->environmt));
    gpps(sesskey, "UserName", "", cfg->username, sizeof(cfg->username));
    gppi(sesskey, "UserNameFromEnvironment", 0, &cfg->username_from_env);
    gpps(sesskey, "LocalUserName", "", cfg->localusername,
	 sizeof(cfg->localusername));
    gppi(sesskey, "NoPTY", 0, &cfg->nopty);
    gppi(sesskey, "Compression", 0, &cfg->compression);
    gppi(sesskey, "TryAgent", 1, &cfg->tryagent);
    gppi(sesskey, "AgentFwd", 0, &cfg->agentfwd);
    gppi(sesskey, "ChangeUsername", 0, &cfg->change_username);
    gppi(sesskey, "GssapiFwd", 0, &cfg->gssapifwd);
    gprefs(sesskey, "Cipher", "\0",
	   ciphernames, CIPHER_MAX, cfg->ssh_cipherlist);
    {
	/* Backward-compatibility: we used to have an option to
	 * disable gex under the "bugs" panel after one report of
	 * a server which offered it then choked, but we never got
	 * a server version string or any other reports. */
	char *default_kexes;
	gppi(sesskey, "BugDHGEx2", 0, &i); i = 2-i;
	if (i == FORCE_ON)
	    default_kexes = "dh-group14-sha1,dh-group1-sha1,rsa,WARN,dh-gex-sha1";
	else
	    default_kexes = "dh-gex-sha1,dh-group14-sha1,dh-group1-sha1,rsa,WARN";
	gprefs(sesskey, "KEX", default_kexes,
	       kexnames, KEX_MAX, cfg->ssh_kexlist);
    }
    gppi(sesskey, "RekeyTime", 60, &cfg->ssh_rekey_time);
    gpps(sesskey, "RekeyBytes", "1G", cfg->ssh_rekey_data,
	 sizeof(cfg->ssh_rekey_data));
    gppi(sesskey, "SshProt", 2, &cfg->sshprot);
    gpps(sesskey, "LogHost", "", cfg->loghost, sizeof(cfg->loghost));
    gppi(sesskey, "SSH2DES", 0, &cfg->ssh2_des_cbc);
    gppi(sesskey, "SshNoAuth", 0, &cfg->ssh_no_userauth);
    gppi(sesskey, "SshBanner", 1, &cfg->ssh_show_banner);
    gppi(sesskey, "AuthTIS", 0, &cfg->try_tis_auth);
    gppi(sesskey, "AuthKI", 1, &cfg->try_ki_auth);
    gppi(sesskey, "AuthGSSAPI", 1, &cfg->try_gssapi_auth);
#ifndef NO_GSSAPI
    gprefs(sesskey, "GSSLibs", "\0",
	   gsslibkeywords, ngsslibs, cfg->ssh_gsslist);
    gppfile(sesskey, "GSSCustom", &cfg->ssh_gss_custom);
#endif
    gppi(sesskey, "SshNoShell", 0, &cfg->ssh_no_shell);
    gppfile(sesskey, "PublicKeyFile", &cfg->keyfile);
    gpps(sesskey, "RemoteCommand", "", cfg->remote_cmd,
	 sizeof(cfg->remote_cmd));
    gppi(sesskey, "RFCEnviron", 0, &cfg->rfc_environ);
    gppi(sesskey, "PassiveTelnet", 0, &cfg->passive_telnet);
    gppi(sesskey, "BackspaceIsDelete", 1, &cfg->bksp_is_delete);
    gppi(sesskey, "RXVTHomeEnd", 0, &cfg->rxvt_homeend);
    gppi(sesskey, "LinuxFunctionKeys", 0, &cfg->funky_type);
    gppi(sesskey, "NoApplicationKeys", 0, &cfg->no_applic_k);
    gppi(sesskey, "NoApplicationCursors", 0, &cfg->no_applic_c);
    gppi(sesskey, "NoMouseReporting", 0, &cfg->no_mouse_rep);
    gppi(sesskey, "NoRemoteResize", 0, &cfg->no_remote_resize);
    gppi(sesskey, "NoAltScreen", 0, &cfg->no_alt_screen);
    gppi(sesskey, "NoRemoteWinTitle", 0, &cfg->no_remote_wintitle);
    {
	/* Backward compatibility */
	int no_remote_qtitle;
	gppi(sesskey, "NoRemoteQTitle", 1, &no_remote_qtitle);
	/* We deliberately interpret the old setting of "no response" as
	 * "empty string". This changes the behaviour, but hopefully for
	 * the better; the user can always recover the old behaviour. */
	gppi(sesskey, "RemoteQTitleAction",
	     no_remote_qtitle ? TITLE_EMPTY : TITLE_REAL,
	     &cfg->remote_qtitle_action);
    }
    gppi(sesskey, "NoDBackspace", 0, &cfg->no_dbackspace);
    gppi(sesskey, "NoRemoteCharset", 0, &cfg->no_remote_charset);
    gppi(sesskey, "ApplicationCursorKeys", 0, &cfg->app_cursor);
    gppi(sesskey, "ApplicationKeypad", 0, &cfg->app_keypad);
    gppi(sesskey, "NetHackKeypad", 0, &cfg->nethack_keypad);
    gppi(sesskey, "AltF4", 1, &cfg->alt_f4);
    gppi(sesskey, "AltSpace", 0, &cfg->alt_space);
    gppi(sesskey, "AltOnly", 0, &cfg->alt_only);
    gppi(sesskey, "AltMetaBit", 0, &cfg->alt_metabit);
    gppi(sesskey, "CtrlTabSwitch", 0, &cfg->ctrl_tab_switch);
    gppi(sesskey, "ComposeKey", 0, &cfg->compose_key);
    gppi(sesskey, "CtrlAltKeys", 1, &cfg->ctrlaltkeys);
    gppi(sesskey, "RightAltKey", 0, &cfg->rightaltkey);
    gppi(sesskey, "TelnetKey", 0, &cfg->telnet_keyboard);
    gppi(sesskey, "TelnetRet", 1, &cfg->telnet_newline);
    gppi(sesskey, "LocalEcho", AUTO, &cfg->localecho);
    gppi(sesskey, "LocalEdit", AUTO, &cfg->localedit);
    gpps(sesskey, "Answerback", "PuTTY", cfg->answerback,
	 sizeof(cfg->answerback));
    gppi(sesskey, "AlwaysOnTop", 0, &cfg->alwaysontop);
    gppi(sesskey, "FullScreenOnAltEnter", 0, &cfg->fullscreenonaltenter);
    gppi(sesskey, "HideMousePtr", 0, &cfg->hide_mouseptr);
    gppi(sesskey, "SunkenEdge", 0, &cfg->sunken_edge);
    gppfile(sesskey, "IconFile", &cfg->iconfile);
    gppi(sesskey, "WindowBorder", 1, &cfg->window_border);
    gppi(sesskey, "CurType", 0, &cfg->cursor_type);
    gppi(sesskey, "BlinkCur", 0, &cfg->blink_cur);
    {
      int key, mod, len;
      char tmp[24];
      char buf[256];
      int max, t;
      for (key = 0; key < 256; key++) {
	sprintf(tmp, "VKey%d", key);
	gpps(sesskey, tmp, "", buf, sizeof(buf));
	max = strlen(buf);
	if (!max) {
	  continue;
	}
	t = 0;
	for (mod = 0; mod < 8; mod++) {
	  for (len = 0; (t < max) && (buf[t] != ',') && (len < 15); len++, t++) {
	    if (buf[t] == '\\') {
	      sscanf(&buf[++t], "%03o", &cfg->pvkey_codes[key][mod][len]);
	      t += 2;
	      continue;
	    }
	    cfg->pvkey_codes[key][mod][len] = buf[t];
	  }
	  cfg->pvkey_length[key][mod] = len;
	  cfg->pvkey_codes[key][mod][len] = '\0';
	  t++;
	}
      }
    }
    /* pedantic compiler tells me I can't use &cfg->beep as an int * :-) */
    gppi(sesskey, "Beep", 1, &cfg->beep);
    gppi(sesskey, "BeepInd", 0, &cfg->beep_ind);
    gppfile(sesskey, "BellWaveFile", &cfg->bell_wavefile);
    gppi(sesskey, "BellOverload", 1, &cfg->bellovl);
    gppi(sesskey, "BellOverloadN", 5, &cfg->bellovl_n);
    gppi(sesskey, "BellOverloadT", 2*TICKSPERSEC
#ifdef PUTTY_UNIX_H
				   *1000
#endif
				   , &i);
    cfg->bellovl_t = i
#ifdef PUTTY_UNIX_H
		    / 1000
#endif
	;
    gppi(sesskey, "BellOverloadS", 5*TICKSPERSEC
#ifdef PUTTY_UNIX_H
				   *1000
#endif
				   , &i);
    cfg->bellovl_s = i
#ifdef PUTTY_UNIX_H
		    / 1000
#endif
	;
    gppi(sesskey, "ScrollbackLines", 200, &cfg->savelines);
    gppi(sesskey, "DECOriginMode", 0, &cfg->dec_om);
    gppi(sesskey, "AutoWrapMode", 1, &cfg->wrap_mode);
    gppi(sesskey, "LFImpliesCR", 0, &cfg->lfhascr);
    gppi(sesskey, "CRImpliesLF", 0, &cfg->crhaslf);
    gppi(sesskey, "DisableArabicShaping", 0, &cfg->arabicshaping);
    gppi(sesskey, "DisableBidi", 0, &cfg->bidi);
    gppi(sesskey, "WinNameAlways", 1, &cfg->win_name_always);
    gpps(sesskey, "WinTitle", "", cfg->wintitle, sizeof(cfg->wintitle));
    gppi(sesskey, "TermWidth", 80, &cfg->width);
    gppi(sesskey, "TermHeight", 24, &cfg->height);
    gppi(sesskey, "TermX", CW_USEDEFAULT, &cfg->x);
    gppi(sesskey, "TermY", CW_USEDEFAULT, &cfg->y);
    gppfont(sesskey, "Font", &cfg->font);
    gppi(sesskey, "FontQuality", FQ_DEFAULT, &cfg->font_quality);
    gppi(sesskey, "FontVTMode", VT_UNICODE, (int *) &cfg->vtmode);
    gppi(sesskey, "UseSystemColours", 0, &cfg->system_colour);
    gppi(sesskey, "TryPalette", 0, &cfg->try_palette);
    gppi(sesskey, "ANSIColour", 1, &cfg->ansi_colour);
    gppi(sesskey, "Xterm256Colour", 1, &cfg->xterm_256_colour);
    gppi(sesskey, "BoldAsColour", 1, &cfg->bold_colour);

    for (i = 0; i < 24; i++) {
	static const char *const defaults[] = {
	    "187,187,187", "255,255,255", "0,0,0", "85,85,85", "0,0,0",
	    "0,255,0", "0,0,0", "85,85,85", "187,0,0", "255,85,85",
	    "0,187,0", "85,255,85", "187,187,0", "255,255,85", "0,0,187",
	    "85,85,255", "187,0,187", "255,85,255", "0,187,187",
	    "85,255,255", "187,187,187", "255,255,255", 
	    "0,0,0", "255,0,0"
  };
	char buf[20], buf2[30];
	int c0, c1, c2;
	sprintf(buf, "Colour%d", i);
	gpps(sesskey, buf, defaults[i], buf2, sizeof(buf2));
	if (sscanf(buf2, "%d,%d,%d", &c0, &c1, &c2) == 3) {
	    cfg->colours[i][0] = c0;
	    cfg->colours[i][1] = c1;
	    cfg->colours[i][2] = c2;
	}
    }
    gppi(sesskey, "RawCNP", 0, &cfg->rawcnp);
    gppi(sesskey, "PasteRTF", 0, &cfg->rtf_paste);
    gpps(sesskey, "IgnoreChars", "", cfg->ignore_chars,
	 sizeof(cfg->ignore_chars));
    gppi(sesskey, "MouseIsXterm", 0, &cfg->mouse_is_xterm);
    gppi(sesskey, "RectSelect", 0, &cfg->rect_select);
    gppi(sesskey, "MouseOverride", 1, &cfg->mouse_override);
    for (i = 0; i < 256; i += 32) {
	static const char *const defaults[] = {
	    "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0",
	    "0,1,2,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1",
	    "1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,2",
	    "1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1",
	    "1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1",
	    "1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1",
	    "2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2",
	    "2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2"
	};
	char buf[20], buf2[256], *p;
	int j;
	sprintf(buf, "Wordness%d", i);
	gpps(sesskey, buf, defaults[i / 32], buf2, sizeof(buf2));
	p = buf2;
	for (j = i; j < i + 32; j++) {
	    char *q = p;
	    while (*p && *p != ',')
		p++;
	    if (*p == ',')
		*p++ = '\0';
	    cfg->wordness[j] = atoi(q);
	}
    }
    /*
     * The empty default for LineCodePage will be converted later
     * into a plausible default for the locale.
     */
    {
      char buf[32];
      get_l10n_setting("_LINECODEPAGE_", buf, sizeof (buf));
      gpps(sesskey, "LineCodePage", buf, cfg->line_codepage,
	 sizeof(cfg->line_codepage));
    }
    if (!strcmp (cfg->line_codepage, "UTF-8")) {
	int i;
	char buf[lenof (cfg->line_codepage)];

	gppi (sesskey, "ISO2022", 0, &i);  /* for compatibility with old patch */
	if (i) {
		strcpy (buf, "iso2022 ");
		gpps (sesskey, "ISO2022initstr", "", &buf[8],
			sizeof buf - 8 * sizeof buf[0]);
		if (buf[8]) memcpy (cfg->line_codepage, buf,
				    sizeof cfg->line_codepage);
	}
    }
    gppi(sesskey, "CJKAmbigWide", 0, &cfg->cjk_ambig_wide);
    gppi(sesskey, "UTF8Override", 1, &cfg->utf8_override);
    gpps(sesskey, "Printer", "", cfg->printer, sizeof(cfg->printer));
    gppi (sesskey, "CapsLockCyr", 0, &cfg->xlat_capslockcyr);
    gppi (sesskey, "Use5Casis", 0, &cfg->use_5casis);
    gppi(sesskey, "ScrollBar", 1, &cfg->scrollbar);
    gppi(sesskey, "ScrollBarFullScreen", 0, &cfg->scrollbar_in_fullscreen);
    gppi(sesskey, "ScrollOnKey", 0, &cfg->scroll_on_key);
    gppi(sesskey, "ScrollOnDisp", 1, &cfg->scroll_on_disp);
    gppi(sesskey, "EraseToScrollback", 1, &cfg->erase_to_scrollback);
    gppi(sesskey, "LockSize", 0, &cfg->resize_action);
    gppi(sesskey, "BCE", 1, &cfg->bce);
    gppi(sesskey, "BlinkText", 0, &cfg->blinktext);
    gppi(sesskey, "X11Forward", 0, &cfg->x11_forward);
    gpps(sesskey, "X11Display", "", cfg->x11_display,
	 sizeof(cfg->x11_display));
    gppi(sesskey, "X11AuthType", X11_MIT, &cfg->x11_auth);
    gppfile(sesskey, "X11AuthFile", &cfg->xauthfile);

    gppi(sesskey, "LocalPortAcceptAll", 0, &cfg->lport_acceptall);
    gppi(sesskey, "RemotePortAcceptAll", 0, &cfg->rport_acceptall);
    gppmap(sesskey, "PortForwardings", "", cfg->portfwd, lenof(cfg->portfwd));
    gppi(sesskey, "BugIgnore1", 0, &i); cfg->sshbug_ignore1 = 2-i;
    gppi(sesskey, "BugPlainPW1", 0, &i); cfg->sshbug_plainpw1 = 2-i;
    gppi(sesskey, "BugRSA1", 0, &i); cfg->sshbug_rsa1 = 2-i;
    gppi(sesskey, "BugIgnore2", 0, &i); cfg->sshbug_ignore2 = 2-i;
    {
	int i;
	gppi(sesskey, "BugHMAC2", 0, &i); cfg->sshbug_hmac2 = 2-i;
	if (cfg->sshbug_hmac2 == AUTO) {
	    gppi(sesskey, "BuggyMAC", 0, &i);
	    if (i == 1)
		cfg->sshbug_hmac2 = FORCE_ON;
	}
    }
    gppi(sesskey, "BugDeriveKey2", 0, &i); cfg->sshbug_derivekey2 = 2-i;
    gppi(sesskey, "BugRSAPad2", 0, &i); cfg->sshbug_rsapad2 = 2-i;
    gppi(sesskey, "BugPKSessID2", 0, &i); cfg->sshbug_pksessid2 = 2-i;
    gppi(sesskey, "BugRekey2", 0, &i); cfg->sshbug_rekey2 = 2-i;
    gppi(sesskey, "BugMaxPkt2", 0, &i); cfg->sshbug_maxpkt2 = 2-i;
    cfg->ssh_simple = FALSE;
    gppi(sesskey, "StampUtmp", 1, &cfg->stamp_utmp);
    gppi(sesskey, "LoginShell", 1, &cfg->login_shell);
    gppi(sesskey, "ScrollbarOnLeft", 0, &cfg->scrollbar_on_left);
    gppi(sesskey, "ShadowBold", 0, &cfg->shadowbold);
    gppfont(sesskey, "BoldFont", &cfg->boldfont);
    gppfont(sesskey, "WideFont", &cfg->widefont);
    gppfont(sesskey, "WideBoldFont", &cfg->wideboldfont);
    gppi(sesskey, "ShadowBoldOffset", 1, &cfg->shadowboldoffset);
    gpps(sesskey, "SerialLine", "", cfg->serline, sizeof(cfg->serline));
    gppi(sesskey, "SerialSpeed", 9600, &cfg->serspeed);
    gppi(sesskey, "SerialDataBits", 8, &cfg->serdatabits);
    gppi(sesskey, "SerialStopHalfbits", 2, &cfg->serstopbits);
    gppi(sesskey, "SerialParity", SER_PAR_NONE, &cfg->serparity);
    gppi(sesskey, "SerialFlowControl", SER_FLOW_XONXOFF, &cfg->serflow);
    gpps(sesskey, "WindowClass", "", cfg->winclass, sizeof(cfg->winclass));

    /* HACK: PuttyTray / Reconnect */
    gppi(sesskey, "WakeupReconnect", 0, &cfg->wakeup_reconnect);
    gppi(sesskey, "FailureReconnect", 0, &cfg->failure_reconnect);

    /* Hyperlink */
    gppi(sesskey, "HyperlinkEnable", 1, &cfg->url_enable);
    gppi(sesskey, "HyperlinkUnderline", 1, &cfg->url_underline);
    gppi(sesskey, "HyperlinkUseCtrlClick", 1, &cfg->url_ctrl_click);

    /* Background */
    gppi(sesskey, "BackgroundWallpaper", 0, &cfg->bg_wallpaper);
    gppi(sesskey, "BackgroundEffect", 0, &cfg->bg_effect);
    gppfile(sesskey, "WallpaperFile", &cfg->wp_file);
    gppi(sesskey, "WallpaperPosition", 0, &cfg->wp_position);
    gppi(sesskey, "WallpaperAlign", 0, &cfg->wp_align);
    gppi(sesskey, "WallpaperVerticalAlign", 0, &cfg->wp_valign);
    gppi(sesskey, "WallpaperMoving", 0, &cfg->wp_moving);

    /* Transparency */
    for (i = 0; i < 4; i++) {
	static const char *const defaults[] = {
	    "100,100", "100,100", "100,100", "100,100"
	};
	char buf[16], buf2[16];
	int c0 = 100;
	int c1 = 100;
	sprintf(buf, "Alpha%d", i);
	gpps(sesskey, buf, defaults[i], buf2, sizeof(buf2));
	if (sscanf(buf2, "%d,%d", &c0, &c1)) {
	    if (c0 > 100) {
		c0 = 100;
	    }
	    if (c1 > 100) {
		c1 = 100;
	    }
	    cfg->alphas_pc[i][0] = c0;
	    cfg->alphas_pc[i][1] = c1;
	}
    }
}
예제 #12
0
/*
 * Pre-initialisation. This is here to get around the fact that GTK
 * doesn't like being run in setuid/setgid programs (probably
 * sensibly). So before we initialise GTK - and therefore before we
 * even process the command line - we check to see if we're running
 * set[ug]id. If so, we open our pty master _now_, chown it as
 * necessary, and drop privileges. We can always close it again
 * later. If we're potentially going to be doing utmp as well, we
 * also fork off a utmp helper process and communicate with it by
 * means of a pipe; the utmp helper will keep privileges in order
 * to clean up utmp when we exit (i.e. when its end of our pipe
 * closes).
 */
void pty_pre_init(void)
{
    Pty pty;

#ifndef OMIT_UTMP
    pid_t pid;
    int pipefd[2];
#endif

    pty = single_pty = snew(struct pty_tag);
    pty->conf = NULL;
    bufchain_init(&pty->output_data);

    /* set the child signal handler straight away; it needs to be set
     * before we ever fork. */
    putty_signal(SIGCHLD, sigchld_handler);
    pty->master_fd = pty->slave_fd = -1;
#ifndef OMIT_UTMP
    pty_stamped_utmp = FALSE;
#endif

    if (geteuid() != getuid() || getegid() != getgid()) {
	pty_open_master(pty);

#ifndef OMIT_UTMP
        /*
         * Fork off the utmp helper.
         */
        if (pipe(pipefd) < 0) {
            perror("pterm: pipe");
            exit(1);
        }
        cloexec(pipefd[0]);
        cloexec(pipefd[1]);
        pid = fork();
        if (pid < 0) {
            perror("pterm: fork");
            exit(1);
        } else if (pid == 0) {
            char display[128], buffer[128];
            int dlen, ret;

            close(pipefd[1]);
            /*
             * Now sit here until we receive a display name from the
             * other end of the pipe, and then stamp utmp. Unstamp utmp
             * again, and exit, when the pipe closes.
             */

            dlen = 0;
            while (1) {
	    
                ret = read(pipefd[0], buffer, lenof(buffer));
                if (ret <= 0) {
                    cleanup_utmp();
                    _exit(0);
                } else if (!pty_stamped_utmp) {
                    if (dlen < lenof(display))
                        memcpy(display+dlen, buffer,
                               min(ret, lenof(display)-dlen));
                    if (buffer[ret-1] == '\0') {
                        /*
                         * Now we have a display name. NUL-terminate
                         * it, and stamp utmp.
                         */
                        display[lenof(display)-1] = '\0';
                        /*
                         * Trap as many fatal signals as we can in the
                         * hope of having the best possible chance to
                         * clean up utmp before termination. We are
                         * unfortunately unprotected against SIGKILL,
                         * but that's life.
                         */
                        putty_signal(SIGHUP, fatal_sig_handler);
                        putty_signal(SIGINT, fatal_sig_handler);
                        putty_signal(SIGQUIT, fatal_sig_handler);
                        putty_signal(SIGILL, fatal_sig_handler);
                        putty_signal(SIGABRT, fatal_sig_handler);
                        putty_signal(SIGFPE, fatal_sig_handler);
                        putty_signal(SIGPIPE, fatal_sig_handler);
                        putty_signal(SIGALRM, fatal_sig_handler);
                        putty_signal(SIGTERM, fatal_sig_handler);
                        putty_signal(SIGSEGV, fatal_sig_handler);
                        putty_signal(SIGUSR1, fatal_sig_handler);
                        putty_signal(SIGUSR2, fatal_sig_handler);
#ifdef SIGBUS
                        putty_signal(SIGBUS, fatal_sig_handler);
#endif
#ifdef SIGPOLL
                        putty_signal(SIGPOLL, fatal_sig_handler);
#endif
#ifdef SIGPROF
                        putty_signal(SIGPROF, fatal_sig_handler);
#endif
#ifdef SIGSYS
                        putty_signal(SIGSYS, fatal_sig_handler);
#endif
#ifdef SIGTRAP
                        putty_signal(SIGTRAP, fatal_sig_handler);
#endif
#ifdef SIGVTALRM
                        putty_signal(SIGVTALRM, fatal_sig_handler);
#endif
#ifdef SIGXCPU
                        putty_signal(SIGXCPU, fatal_sig_handler);
#endif
#ifdef SIGXFSZ
                        putty_signal(SIGXFSZ, fatal_sig_handler);
#endif
#ifdef SIGIO
                        putty_signal(SIGIO, fatal_sig_handler);
#endif
                        setup_utmp(pty->name, display);
                    }
                }
            }
        } else {
            close(pipefd[0]);
            pty_utmp_helper_pid = pid;
            pty_utmp_helper_pipe = pipefd[1];
        }
#endif
    }

    /* Drop privs. */
    {
#ifndef HAVE_NO_SETRESUID
	int gid = getgid(), uid = getuid();
	int setresgid(gid_t, gid_t, gid_t);
	int setresuid(uid_t, uid_t, uid_t);
	if (setresgid(gid, gid, gid) < 0) {
            perror("setresgid");
            exit(1);
        }
	if (setresuid(uid, uid, uid) < 0) {
            perror("setresuid");
            exit(1);
        }
#else
	if (setgid(getgid()) < 0) {
            perror("setgid");
            exit(1);
        }
	if (setuid(getuid()) < 0) {
            perror("setuid");
            exit(1);
        }
#endif
    }
}
예제 #13
0
파일: proxy.c 프로젝트: FauxFaux/PuTTYTray
Socket new_connection(SockAddr addr,
                      const char *hostname,
                      int port,
                      int privport,
                      int oobinline,
                      int nodelay,
                      int keepalive,
                      Plug plug,
                      Conf *conf)
{
  static const struct socket_function_table socket_fn_table = {
      sk_proxy_plug,
      sk_proxy_close,
      sk_proxy_write,
      sk_proxy_write_oob,
      sk_proxy_write_eof,
      sk_proxy_flush,
      sk_proxy_set_frozen,
      sk_proxy_socket_error,
      NULL, /* peer_info */
  };

  static const struct plug_function_table plug_fn_table = {
      plug_proxy_log,
      plug_proxy_closing,
      plug_proxy_receive,
      plug_proxy_sent,
      plug_proxy_accepting};

  if (conf_get_int(conf, CONF_proxy_type) != PROXY_NONE &&
      proxy_for_destination(addr, hostname, port, conf)) {
    Proxy_Socket ret;
    Proxy_Plug pplug;
    SockAddr proxy_addr;
    char *proxy_canonical_name;
    const char *proxy_type;
    Socket sret;
    int type;

    if ((sret = platform_new_connection(addr,
                                        hostname,
                                        port,
                                        privport,
                                        oobinline,
                                        nodelay,
                                        keepalive,
                                        plug,
                                        conf)) != NULL)
      return sret;

    ret = snew(struct Socket_proxy_tag);
    ret->fn = &socket_fn_table;
    ret->conf = conf_copy(conf);
    ret->plug = plug;
    ret->remote_addr = addr; /* will need to be freed on close */
    ret->remote_port = port;

    ret->error = NULL;
    ret->pending_flush = 0;
    ret->pending_eof = 0;
    ret->freeze = 0;

    bufchain_init(&ret->pending_input_data);
    bufchain_init(&ret->pending_output_data);
    bufchain_init(&ret->pending_oob_output_data);

    ret->sub_socket = NULL;
    ret->state = PROXY_STATE_NEW;
    ret->negotiate = NULL;

    type = conf_get_int(conf, CONF_proxy_type);
    if (type == PROXY_HTTP) {
      ret->negotiate = proxy_http_negotiate;
      proxy_type = "HTTP";
    } else if (type == PROXY_SOCKS4) {
      ret->negotiate = proxy_socks4_negotiate;
      proxy_type = "SOCKS 4";
    } else if (type == PROXY_SOCKS5) {
      ret->negotiate = proxy_socks5_negotiate;
      proxy_type = "SOCKS 5";
    } else if (type == PROXY_TELNET) {
      ret->negotiate = proxy_telnet_negotiate;
      proxy_type = "Telnet";
    } else {
      ret->error = "Proxy error: Unknown proxy method";
      return (Socket)ret;
    }

    {
      char *logmsg = dupprintf("Will use %s proxy at %s:%d to connect"
                               " to %s:%d",
                               proxy_type,
                               conf_get_str(conf, CONF_proxy_host),
                               conf_get_int(conf, CONF_proxy_port),
                               hostname,
                               port);
      plug_log(plug, 2, NULL, 0, logmsg, 0);
      sfree(logmsg);
    }

    /* create the proxy plug to map calls from the actual
     * socket into our proxy socket layer */
    pplug = snew(struct Plug_proxy_tag);
    pplug->fn = &plug_fn_table;
    pplug->proxy_socket = ret;

    {
      char *logmsg = dns_log_msg(conf_get_str(conf, CONF_proxy_host),
                                 conf_get_int(conf, CONF_addressfamily),
                                 "proxy");
      plug_log(plug, 2, NULL, 0, logmsg, 0);
      sfree(logmsg);
    }

    /* look-up proxy */
    proxy_addr = sk_namelookup(conf_get_str(conf, CONF_proxy_host),
                               &proxy_canonical_name,
                               conf_get_int(conf, CONF_addressfamily));
    if (sk_addr_error(proxy_addr) != NULL) {
      ret->error = "Proxy error: Unable to resolve proxy host name";
      sfree(pplug);
      sk_addr_free(proxy_addr);
      return (Socket)ret;
    }
    sfree(proxy_canonical_name);

    {
      char addrbuf[256], *logmsg;
      sk_getaddr(proxy_addr, addrbuf, lenof(addrbuf));
      logmsg = dupprintf("Connecting to %s proxy at %s port %d",
                         proxy_type,
                         addrbuf,
                         conf_get_int(conf, CONF_proxy_port));
      plug_log(plug, 2, NULL, 0, logmsg, 0);
      sfree(logmsg);
    }

    /* create the actual socket we will be using,
     * connected to our proxy server and port.
     */
    ret->sub_socket = sk_new(proxy_addr,
                             conf_get_int(conf, CONF_proxy_port),
                             privport,
                             oobinline,
                             nodelay,
                             keepalive,
                             (Plug)pplug);
    if (sk_socket_error(ret->sub_socket) != NULL)
      return (Socket)ret;

    /* start the proxy negotiation process... */
    sk_set_frozen(ret->sub_socket, 0);
    ret->negotiate(ret, PROXY_CHANGE_NEW);

    return (Socket)ret;
  }
예제 #14
0
int main(int argc, char **argv)
{
    bool sending;
    SOCKET *sklist;
    size_t skcount, sksize;
    int exitcode;
    bool errors;
    bool use_subsystem = false;
    bool just_test_share_exists = false;
    enum TriState sanitise_stdout = AUTO, sanitise_stderr = AUTO;
    unsigned long now, next, then;
    const struct BackendVtable *vt;

    dll_hijacking_protection();

    sklist = NULL;
    skcount = sksize = 0;
    /*
     * Initialise port and protocol to sensible defaults. (These
     * will be overridden by more or less anything.)
     */
    default_protocol = PROT_SSH;
    default_port = 22;

    flags = 0;
    cmdline_tooltype |=
        (TOOLTYPE_HOST_ARG |
         TOOLTYPE_HOST_ARG_CAN_BE_SESSION |
         TOOLTYPE_HOST_ARG_PROTOCOL_PREFIX |
         TOOLTYPE_HOST_ARG_FROM_LAUNCHABLE_LOAD);

    /*
     * Process the command line.
     */
    conf = conf_new();
    do_defaults(NULL, conf);
    loaded_session = false;
    default_protocol = conf_get_int(conf, CONF_protocol);
    default_port = conf_get_int(conf, CONF_port);
    errors = false;
    {
	/*
	 * Override the default protocol if PLINK_PROTOCOL is set.
	 */
	char *p = getenv("PLINK_PROTOCOL");
	if (p) {
            const struct BackendVtable *vt = backend_vt_from_name(p);
            if (vt) {
                default_protocol = vt->protocol;
                default_port = vt->default_port;
		conf_set_int(conf, CONF_protocol, default_protocol);
		conf_set_int(conf, CONF_port, default_port);
	    }
	}
    }
    while (--argc) {
	char *p = *++argv;
        int ret = cmdline_process_param(p, (argc > 1 ? argv[1] : NULL),
                                        1, conf);
        if (ret == -2) {
            fprintf(stderr,
                    "plink: option \"%s\" requires an argument\n", p);
            errors = true;
        } else if (ret == 2) {
            --argc, ++argv;
        } else if (ret == 1) {
            continue;
        } else if (!strcmp(p, "-batch")) {
            console_batch_mode = true;
        } else if (!strcmp(p, "-s")) {
            /* Save status to write to conf later. */
            use_subsystem = true;
        } else if (!strcmp(p, "-V") || !strcmp(p, "--version")) {
            version();
        } else if (!strcmp(p, "--help")) {
            usage();
        } else if (!strcmp(p, "-pgpfp")) {
            pgp_fingerprints();
            exit(1);
        } else if (!strcmp(p, "-shareexists")) {
            just_test_share_exists = true;
        } else if (!strcmp(p, "-sanitise-stdout") ||
                   !strcmp(p, "-sanitize-stdout")) {
            sanitise_stdout = FORCE_ON;
        } else if (!strcmp(p, "-no-sanitise-stdout") ||
                   !strcmp(p, "-no-sanitize-stdout")) {
            sanitise_stdout = FORCE_OFF;
        } else if (!strcmp(p, "-sanitise-stderr") ||
                   !strcmp(p, "-sanitize-stderr")) {
            sanitise_stderr = FORCE_ON;
        } else if (!strcmp(p, "-no-sanitise-stderr") ||
                   !strcmp(p, "-no-sanitize-stderr")) {
            sanitise_stderr = FORCE_OFF;
        } else if (!strcmp(p, "-no-antispoof")) {
            console_antispoof_prompt = false;
	} else if (*p != '-') {
            strbuf *cmdbuf = strbuf_new();

            while (argc > 0) {
                if (cmdbuf->len > 0)
                    put_byte(cmdbuf, ' '); /* add space separator */
                put_datapl(cmdbuf, ptrlen_from_asciz(p));
                if (--argc > 0)
                    p = *++argv;
            }

            conf_set_str(conf, CONF_remote_cmd, cmdbuf->s);
            conf_set_str(conf, CONF_remote_cmd2, "");
            conf_set_bool(conf, CONF_nopty, true);  /* command => no tty */

            strbuf_free(cmdbuf);
            break;		       /* done with cmdline */
        } else {
            fprintf(stderr, "plink: unknown option \"%s\"\n", p);
            errors = true;
        }
    }

    if (errors)
	return 1;

    if (!cmdline_host_ok(conf)) {
	usage();
    }

    prepare_session(conf);

    /*
     * Perform command-line overrides on session configuration.
     */
    cmdline_run_saved(conf);

    /*
     * Apply subsystem status.
     */
    if (use_subsystem)
        conf_set_bool(conf, CONF_ssh_subsys, true);

    if (!*conf_get_str(conf, CONF_remote_cmd) &&
	!*conf_get_str(conf, CONF_remote_cmd2) &&
	!*conf_get_str(conf, CONF_ssh_nc_host))
	flags |= FLAG_INTERACTIVE;

    /*
     * Select protocol. This is farmed out into a table in a
     * separate file to enable an ssh-free variant.
     */
    vt = backend_vt_from_proto(conf_get_int(conf, CONF_protocol));
    if (vt == NULL) {
	fprintf(stderr,
		"Internal fault: Unsupported protocol found\n");
	return 1;
    }

    sk_init();
    if (p_WSAEventSelect == NULL) {
	fprintf(stderr, "Plink requires WinSock 2\n");
	return 1;
    }

    /*
     * Plink doesn't provide any way to add forwardings after the
     * connection is set up, so if there are none now, we can safely set
     * the "simple" flag.
     */
    if (conf_get_int(conf, CONF_protocol) == PROT_SSH &&
	!conf_get_bool(conf, CONF_x11_forward) &&
	!conf_get_bool(conf, CONF_agentfwd) &&
	!conf_get_str_nthstrkey(conf, CONF_portfwd, 0))
	conf_set_bool(conf, CONF_ssh_simple, true);

    logctx = log_init(default_logpolicy, conf);

    if (just_test_share_exists) {
        if (!vt->test_for_upstream) {
            fprintf(stderr, "Connection sharing not supported for connection "
                    "type '%s'\n", vt->name);
            return 1;
        }
        if (vt->test_for_upstream(conf_get_str(conf, CONF_host),
                                  conf_get_int(conf, CONF_port), conf))
            return 0;
        else
            return 1;
    }

    if (restricted_acl) {
        lp_eventlog(default_logpolicy, "Running with restricted process ACL");
    }

    /*
     * Start up the connection.
     */
    netevent = CreateEvent(NULL, false, false, NULL);
    {
	const char *error;
	char *realhost;
	/* nodelay is only useful if stdin is a character device (console) */
	bool nodelay = conf_get_bool(conf, CONF_tcp_nodelay) &&
	    (GetFileType(GetStdHandle(STD_INPUT_HANDLE)) == FILE_TYPE_CHAR);

        error = backend_init(vt, plink_seat, &backend, logctx, conf,
                             conf_get_str(conf, CONF_host),
                             conf_get_int(conf, CONF_port),
                             &realhost, nodelay,
                             conf_get_bool(conf, CONF_tcp_keepalives));
	if (error) {
	    fprintf(stderr, "Unable to open connection:\n%s", error);
	    return 1;
	}
	sfree(realhost);
    }

    inhandle = GetStdHandle(STD_INPUT_HANDLE);
    outhandle = GetStdHandle(STD_OUTPUT_HANDLE);
    errhandle = GetStdHandle(STD_ERROR_HANDLE);

    /*
     * Turn off ECHO and LINE input modes. We don't care if this
     * call fails, because we know we aren't necessarily running in
     * a console.
     */
    GetConsoleMode(inhandle, &orig_console_mode);
    SetConsoleMode(inhandle, ENABLE_PROCESSED_INPUT);

    /*
     * Pass the output handles to the handle-handling subsystem.
     * (The input one we leave until we're through the
     * authentication process.)
     */
    stdout_handle = handle_output_new(outhandle, stdouterr_sent, NULL, 0);
    stderr_handle = handle_output_new(errhandle, stdouterr_sent, NULL, 0);
    handle_sink_init(&stdout_hs, stdout_handle);
    handle_sink_init(&stderr_hs, stderr_handle);
    stdout_bs = BinarySink_UPCAST(&stdout_hs);
    stderr_bs = BinarySink_UPCAST(&stderr_hs);

    /*
     * Decide whether to sanitise control sequences out of standard
     * output and standard error.
     *
     * If we weren't given a command-line override, we do this if (a)
     * the fd in question is pointing at a console, and (b) we aren't
     * trying to allocate a terminal as part of the session.
     *
     * (Rationale: the risk of control sequences is that they cause
     * confusion when sent to a local console, so if there isn't one,
     * no problem. Also, if we allocate a remote terminal, then we
     * sent a terminal type, i.e. we told it what kind of escape
     * sequences we _like_, i.e. we were expecting to receive some.)
     */
    if (sanitise_stdout == FORCE_ON ||
        (sanitise_stdout == AUTO && is_console_handle(outhandle) &&
         conf_get_bool(conf, CONF_nopty))) {
        stdout_scc = stripctrl_new(stdout_bs, true, L'\0');
        stdout_bs = BinarySink_UPCAST(stdout_scc);
    }
    if (sanitise_stderr == FORCE_ON ||
        (sanitise_stderr == AUTO && is_console_handle(errhandle) &&
         conf_get_bool(conf, CONF_nopty))) {
        stderr_scc = stripctrl_new(stderr_bs, true, L'\0');
        stderr_bs = BinarySink_UPCAST(stderr_scc);
    }

    main_thread_id = GetCurrentThreadId();

    sending = false;

    now = GETTICKCOUNT();

    while (1) {
	int nhandles;
	HANDLE *handles;	
	int n;
	DWORD ticks;

        if (!sending && backend_sendok(backend)) {
	    stdin_handle = handle_input_new(inhandle, stdin_gotdata, NULL,
					    0);
	    sending = true;
	}

        if (toplevel_callback_pending()) {
            ticks = 0;
            next = now;
        } else if (run_timers(now, &next)) {
	    then = now;
	    now = GETTICKCOUNT();
	    if (now - then > next - then)
		ticks = 0;
	    else
		ticks = next - now;
	} else {
	    ticks = INFINITE;
            /* no need to initialise next here because we can never
             * get WAIT_TIMEOUT */
	}

	handles = handle_get_events(&nhandles);
	handles = sresize(handles, nhandles+1, HANDLE);
	handles[nhandles] = netevent;
	n = MsgWaitForMultipleObjects(nhandles+1, handles, false, ticks,
				      QS_POSTMESSAGE);
	if ((unsigned)(n - WAIT_OBJECT_0) < (unsigned)nhandles) {
	    handle_got_event(handles[n - WAIT_OBJECT_0]);
	} else if (n == WAIT_OBJECT_0 + nhandles) {
	    WSANETWORKEVENTS things;
	    SOCKET socket;
	    int i, socketstate;

	    /*
	     * We must not call select_result() for any socket
	     * until we have finished enumerating within the tree.
	     * This is because select_result() may close the socket
	     * and modify the tree.
	     */
	    /* Count the active sockets. */
	    i = 0;
	    for (socket = first_socket(&socketstate);
		 socket != INVALID_SOCKET;
		 socket = next_socket(&socketstate)) i++;

	    /* Expand the buffer if necessary. */
            sgrowarray(sklist, sksize, i);

	    /* Retrieve the sockets into sklist. */
	    skcount = 0;
	    for (socket = first_socket(&socketstate);
		 socket != INVALID_SOCKET;
		 socket = next_socket(&socketstate)) {
		sklist[skcount++] = socket;
	    }

	    /* Now we're done enumerating; go through the list. */
	    for (i = 0; i < skcount; i++) {
		WPARAM wp;
		socket = sklist[i];
		wp = (WPARAM) socket;
		if (!p_WSAEnumNetworkEvents(socket, NULL, &things)) {
                    static const struct { int bit, mask; } eventtypes[] = {
                        {FD_CONNECT_BIT, FD_CONNECT},
                        {FD_READ_BIT, FD_READ},
                        {FD_CLOSE_BIT, FD_CLOSE},
                        {FD_OOB_BIT, FD_OOB},
                        {FD_WRITE_BIT, FD_WRITE},
                        {FD_ACCEPT_BIT, FD_ACCEPT},
                    };
                    int e;

		    noise_ultralight(NOISE_SOURCE_IOID, socket);

                    for (e = 0; e < lenof(eventtypes); e++)
                        if (things.lNetworkEvents & eventtypes[e].mask) {
                            LPARAM lp;
                            int err = things.iErrorCode[eventtypes[e].bit];
                            lp = WSAMAKESELECTREPLY(eventtypes[e].mask, err);
                            select_result(wp, lp);
                        }
		}
	    }
	} else if (n == WAIT_OBJECT_0 + nhandles + 1) {
	    MSG msg;
	    while (PeekMessage(&msg, INVALID_HANDLE_VALUE,
			       WM_AGENT_CALLBACK, WM_AGENT_CALLBACK,
			       PM_REMOVE)) {
		struct agent_callback *c = (struct agent_callback *)msg.lParam;
		c->callback(c->callback_ctx, c->data, c->len);
		sfree(c);
	    }
	}

        run_toplevel_callbacks();

	if (n == WAIT_TIMEOUT) {
	    now = next;
	} else {
	    now = GETTICKCOUNT();
	}

	sfree(handles);

	if (sending)
            handle_unthrottle(stdin_handle, backend_sendbuffer(backend));

        if (!backend_connected(backend) &&
	    handle_backlog(stdout_handle) + handle_backlog(stderr_handle) == 0)
	    break;		       /* we closed the connection */
    }
    exitcode = backend_exitcode(backend);
    if (exitcode < 0) {
	fprintf(stderr, "Remote process exit code unavailable\n");
	exitcode = 1;		       /* this is an error condition */
    }
    cleanup_exit(exitcode);
    return 0;			       /* placate compiler warning */
}
예제 #15
0
파일: fcgi-utils.c 프로젝트: michals/sx
static void auth_begin(void) {
    const char *param = FCGX_GetParam("HTTP_AUTHORIZATION", envp);
    uint8_t buf[AUTHTOK_BIN_LEN], key[AUTH_KEY_LEN];
    unsigned int blen = sizeof(buf);
    time_t reqdate, now;

    if(!param || strlen(param) != lenof("SKY ") + AUTHTOK_ASCII_LEN || strncmp(param, "SKY ", 4))
	return;

    if(sxi_b64_dec_core(param+4, buf, &blen) || blen != sizeof(buf))
	return;
    memcpy(user, buf, sizeof(user));
    memcpy(rhmac, buf+20, sizeof(rhmac));

    if(sx_hashfs_get_user_info(hashfs, user, &uid, key, &role) != OK) /* no such user */ {
        WARN("No such user: %s", param+4);
       return;
    }
    DEBUG("Request from uid %lld", (long long)uid);

    if(!sxi_hmac_init_ex(&hmac_ctx, key, sizeof(key), EVP_sha1(), NULL)) {
        WARN("hmac_init failed");
        quit_errmsg(500, "Failed to initialize crypto engine");
    }

    param = FCGX_GetParam("REQUEST_METHOD", envp);
    if(!param)
	return;
    if(!hmac_update_str(&hmac_ctx, param))
        quit_errmsg(500, "Failed to initialize crypto engine");

    param = FCGX_GetParam("REQUEST_URI", envp);
    if(!param)
	return;
    if(!hmac_update_str(&hmac_ctx, param+1))
        quit_errmsg(500, "Failed to initialize crypto engine");

    param = FCGX_GetParam("HTTP_DATE", envp);
    if(!param)
        quit_errmsg(400, "Missing Date: header");
    if(httpdate_to_time_t(param, &reqdate))
        quit_errmsg(400, "Date header in wrong format");
    now = time(NULL);
    if(reqdate < now - MAX_CLOCK_DRIFT * 60 || reqdate > now + MAX_CLOCK_DRIFT * 60)
        quit_errmsg(400, "Client clock drifted more than "STRIFY(MAX_CLOCK_DRIFT)" minutes");
    if(!hmac_update_str(&hmac_ctx, param))
        quit_errmsg(500, "Failed to initialize crypto engine");

    if(!content_len()) {
	uint8_t chmac[20];
	unsigned int chmac_len = 20;
	if(!hmac_update_str(&hmac_ctx, "da39a3ee5e6b4b0d3255bfef95601890afd80709"))
            quit_errmsg(500, "Failed to initialize crypto engine");
	if(!sxi_hmac_final(&hmac_ctx, chmac, &chmac_len))
            quit_errmsg(500, "Failed to initialize crypto engine");
	if(!hmac_compare(chmac, rhmac, sizeof(rhmac))) {
	    authed = AUTH_OK;
	} else {
	    /* WARN("auth mismatch"); */
	}
	return;
    } else
	authed = AUTH_BODYCHECK;
}
예제 #16
0
static int asn1_get_rsa_pubkey(fmap_t *map, const void **asn1data, unsigned int *size, cli_crt *x509) {
    struct cli_asn1 obj;
    unsigned int avail, avail2;

    if(asn1_expect_objtype(map, *asn1data, size, &obj, 0x30)) /* subjectPublicKeyInfo */
	return 1;
    *asn1data = obj.next;

    avail = obj.size;
    if(asn1_expect_algo(map, &obj.content, &avail, lenof(OID_rsaEncryption), OID_rsaEncryption)) /* rsaEncryption */
       return 1;

    if(asn1_expect_objtype(map, obj.content, &avail, &obj, 0x03)) /* BIT STRING - subjectPublicKey */
	return 1;
    if(avail) {
	cli_dbgmsg("asn1_get_rsa_pubkey: found unexpected extra data in subjectPublicKeyInfo\n");
	return 1;
    }
    /* if(obj.size != 141 && obj.size != 271) /\* encoded len of 1024 and 2048 bit public keys *\/ */
    /*	return 1; */

    if(!fmap_need_ptr_once(map, obj.content, 1)) {
	cli_dbgmsg("asn1_get_rsa_pubkey: cannot read public key content\n");
	return 1;
    }
    if(((uint8_t *)obj.content)[0] != 0) { /* no byte fragments */
	cli_dbgmsg("asn1_get_rsa_pubkey: unexpected byte frags in public key\n");
	return 1;
    }

    avail = obj.size - 1;
    obj.content = ((uint8_t *)obj.content) + 1;
    if(asn1_expect_objtype(map, obj.content, &avail, &obj, 0x30)) /* SEQUENCE */
	return 1;
    if(avail) {
	cli_dbgmsg("asn1_get_rsa_pubkey: found unexpected extra data in public key content\n");
	return 1;
    }

    avail = obj.size;
    if(asn1_expect_objtype(map, obj.content, &avail, &obj, 0x02)) /* INTEGER - mod */
	return 1;
    if(obj.size < 1024/8 || obj.size > 4096/8+1) {
	cli_dbgmsg("asn1_get_rsa_pubkey: modulus has got an unsupported length (%u)\n",	 obj.size * 8);
	return 1;
    }
    avail2 = obj.size;
    if(!fmap_need_ptr_once(map, obj.content, avail2)) {
	cli_dbgmsg("asn1_get_rsa_pubkey: cannot read n\n");
	return 1;
    }
    if(mp_read_unsigned_bin(&x509->n, obj.content, avail2)) {
	cli_dbgmsg("asn1_get_rsa_pubkey: cannot convert n to big number\n");
	return 1;
    }

    if(asn1_expect_objtype(map, obj.next, &avail, &obj, 0x02)) /* INTEGER - exp */
	return 1;
    if(avail) {
	cli_dbgmsg("asn1_get_rsa_pubkey: found unexpected extra data after exp\n");
	return 1;
    }
    if(obj.size < 1 || obj.size > avail2) {
	cli_dbgmsg("asn1_get_rsa_pubkey: exponent has got an unsupported length (%u)\n",  obj.size * 8);
	return 1;
    }
    if(!fmap_need_ptr_once(map, obj.content, obj.size)) {
	cli_dbgmsg("asn1_get_rsa_pubkey: cannot read e\n");
	return 1;
    }
    if(mp_read_unsigned_bin(&x509->e, obj.content, obj.size)) {
	cli_dbgmsg("asn1_get_rsa_pubkey: cannot convert e to big number\n");
	return 1;
    }
    return 0;
}
예제 #17
0
static int asn1_parse_mscat(fmap_t *map, size_t offset, unsigned int size, crtmgr *cmgr, int embedded, const void **hashes, unsigned int *hashes_size, struct cl_engine *engine) {
    struct cli_asn1 asn1, deep, deeper;
    uint8_t sha1[SHA1_HASH_SIZE], issuer[SHA1_HASH_SIZE], md[SHA1_HASH_SIZE], serial[SHA1_HASH_SIZE];
    const uint8_t *message, *attrs;
    unsigned int dsize, message_size, attrs_size;
    cli_crt_hashtype hashtype;
    cli_crt *x509;
    void *ctx;
    int result;
    int isBlacklisted = 0;

    cli_dbgmsg("in asn1_parse_mscat\n");

    do {
	if(!(message = fmap_need_off_once(map, offset, 1))) {
	    cli_dbgmsg("asn1_parse_mscat: failed to read pkcs#7 entry\n");
	    break;
	}

	if(asn1_expect_objtype(map, message, &size, &asn1, 0x30)) /* SEQUENCE */
	    break;
	/* if(size) { */
	/*     cli_dbgmsg("asn1_parse_mscat: found extra data after pkcs#7 %u\n", size); */
	/*     break; */
	/* } */
	size = asn1.size;
	if(asn1_expect_obj(map, &asn1.content, &size, 0x06, lenof(OID_signedData), OID_signedData)) /* OBJECT 1.2.840.113549.1.7.2 - contentType = signedData */
	    break;
	if(asn1_expect_objtype(map, asn1.content, &size, &asn1, 0xa0)) /* [0] - content */
	    break;
	if(size) {
	    cli_dbgmsg("asn1_parse_mscat: found extra data in pkcs#7\n");
	    break;
	}
	size = asn1.size;
	if(asn1_expect_objtype(map, asn1.content, &size, &asn1, 0x30)) /* SEQUENCE */
	    break;
	if(size) {
	    cli_dbgmsg("asn1_parse_mscat: found extra data in signedData\n");
	    break;
	}
	size = asn1.size;
	if(asn1_expect_obj(map, &asn1.content, &size, 0x02, 1, "\x01")) /* INTEGER - VERSION 1 */
	    break;

	if(asn1_expect_objtype(map, asn1.content, &size, &asn1, 0x31)) /* SET OF DigestAlgorithmIdentifier */
	    break;

	if(asn1_expect_algo(map, &asn1.content, &asn1.size, lenof(OID_sha1), OID_sha1)) /* DigestAlgorithmIdentifier[0] == sha1 */
	    break;
	if(asn1.size) {
	    cli_dbgmsg("asn1_parse_mscat: only one digestAlgorithmIdentifier is allowed\n");
	    break;
	}

	if(asn1_expect_objtype(map, asn1.next, &size, &asn1, 0x30)) /* SEQUENCE - contentInfo */
	    break;
	/* Here there is either a PKCS #7 ContentType Object Identifier for Certificate Trust List (szOID_CTL)
	 * or a single SPC_INDIRECT_DATA_OBJID */
	if(
	   (!embedded && asn1_expect_obj(map, &asn1.content, &asn1.size, 0x06, lenof(OID_szOID_CTL), OID_szOID_CTL)) ||
	   (embedded && asn1_expect_obj(map, &asn1.content, &asn1.size, 0x06, lenof(OID_SPC_INDIRECT_DATA_OBJID), OID_SPC_INDIRECT_DATA_OBJID))
	   )
	    break;

	if(asn1_expect_objtype(map, asn1.content, &asn1.size, &deep, 0xa0))
	    break;
	if(asn1.size) {
	    cli_dbgmsg("asn1_parse_mscat: found extra data in contentInfo\n");
	    break;
	}
	dsize = deep.size;
	if(asn1_expect_objtype(map, deep.content, &dsize, &deep, 0x30))
	    break;
	if(dsize) {
	    cli_dbgmsg("asn1_parse_mscat: found extra data in content\n");
	    break;
	}
	*hashes = deep.content;
	*hashes_size = deep.size;

	if(asn1_expect_objtype(map, asn1.next, &size, &asn1, 0xa0)) /* certificates */
	    break;

	dsize = asn1.size;
	if(dsize) {
	    crtmgr newcerts;
	    crtmgr_init(&newcerts);
	    while(dsize) {
		if(asn1_get_x509(map, &asn1.content, &dsize, cmgr, &newcerts)) {
		    dsize = 1;
		    break;
		}
	    }
	    if(dsize)
		break;
	    if(newcerts.crts) {
		x509 = newcerts.crts;
		cli_dbgmsg("asn1_parse_mscat: %u new certificates collected\n", newcerts.items);
		while(x509) {
		    cli_crt *parent = crtmgr_verify_crt(cmgr, x509);

            /* Dump the cert if requested before anything happens to it */
            if (engine->dconf->pe & PE_CONF_DUMPCERT) {
                char issuer[SHA1_HASH_SIZE*2+1], subject[SHA1_HASH_SIZE*2+1], serial[SHA1_HASH_SIZE*2+1];
                char mod[1024], exp[1024];
                int j=1024;

                fp_toradix_n(&x509->n, mod, 16, j);
                fp_toradix_n(&x509->e, exp, 16, j);
                for (j=0; j < SHA1_HASH_SIZE; j++) {
                    sprintf(&issuer[j*2], "%02x", x509->issuer[j]);
                    sprintf(&subject[j*2], "%02x", x509->subject[j]);
                    sprintf(&serial[j*2], "%02x", x509->serial[j]);
                }

                cli_dbgmsg_internal("cert subject:%s serial:%s pubkey:%s i:%s %lu->%lu %s %s %s\n", subject, serial, mod, issuer, (unsigned long)x509->not_before, (unsigned long)x509->not_after, x509->certSign ? "cert" : "", x509->codeSign ? "code" : "", x509->timeSign ? "time" : "");
            }

		    if(parent) {
                if (parent->isBlacklisted) {
                    isBlacklisted = 1;
                    cli_dbgmsg("asn1_parse_mscat: Authenticode certificate %s is revoked. Flagging sample as virus.\n", (parent->name ? parent->name : "(no name)"));
                }

			x509->codeSign &= parent->codeSign;
			x509->timeSign &= parent->timeSign;
            if(crtmgr_add(cmgr, x509))
                break;
            crtmgr_del(&newcerts, x509);
			x509 = newcerts.crts;
			continue;
		    }
		    x509 = x509->next;
		}
		if(x509)
		    break;
		if(newcerts.items)
		    cli_dbgmsg("asn1_parse_mscat: %u certificates did not verify\n", newcerts.items);
		crtmgr_free(&newcerts);
	    }
	}

	if(asn1_get_obj(map, asn1.next, &size, &asn1))
	    break;
	if(asn1.type == 0xa1 && asn1_get_obj(map, asn1.next, &size, &asn1)) /* crls - unused shouldn't be present */
	    break;
	if(asn1.type != 0x31) { /* signerInfos */
	    cli_dbgmsg("asn1_parse_mscat: unexpected type %02x for signerInfos\n", asn1.type);
	    break;
	}
	if(size) {
	    cli_dbgmsg("asn1_parse_mscat: unexpected extra data after signerInfos\n");
	    break;
	}
	size = asn1.size;
	if(asn1_expect_objtype(map, asn1.content, &size, &asn1, 0x30))
	    break;
	if(size) {
	    cli_dbgmsg("asn1_parse_mscat: only one signerInfo shall be present\n");
	    break;
	}
	size = asn1.size;
	if(asn1_expect_obj(map, &asn1.content, &size, 0x02, 1, "\x01")) /* Version = 1 */
	    break;
	if(asn1_expect_objtype(map, asn1.content, &size, &asn1, 0x30)) /* issuerAndSerialNumber */
	    break;
	dsize = asn1.size;
	if(asn1_expect_objtype(map, asn1.content, &dsize, &deep, 0x30)) /* issuer */
	    break;
	if(map_sha1(map, deep.content, deep.size, issuer))
	    break;

	if(asn1_expect_objtype(map, deep.next, &dsize, &deep, 0x02)) /* serial */
	    break;
	if(map_sha1(map, deep.content, deep.size, serial))
	    break;
	if(dsize) {
	    cli_dbgmsg("asn1_parse_mscat: extra data inside issuerAndSerialNumber\n");
	    break;
	}
	if(asn1_expect_algo(map, &asn1.next, &size, lenof(OID_sha1), OID_sha1)) /* digestAlgorithm == sha1 */
	    break;

	attrs = asn1.next;
	if(asn1_expect_objtype(map, asn1.next, &size, &asn1, 0xa0)) /* authenticatedAttributes */
	    break;
	attrs_size = (uint8_t *)(asn1.next) - attrs;
	if(attrs_size < 2) {
	    cli_dbgmsg("asn1_parse_mscat: authenticatedAttributes size is too small\n");
	    break;
	}

	dsize = asn1.size;
	deep.next = asn1.content;
	result = 0;
	while(dsize) {
	    struct cli_asn1 cobj;
	    int content;
	    if(asn1_expect_objtype(map, deep.next, &dsize, &deep, 0x30)) { /* attribute */
		dsize = 1;
		break;
	    }
	    if(asn1_expect_objtype(map, deep.content, &deep.size, &deeper, 0x06)) { /* attribute type */
		dsize = 1;
		break;
	    }
	    if(deeper.size != lenof(OID_contentType))
		continue;
	    if(!fmap_need_ptr_once(map, deeper.content, lenof(OID_contentType))) {
		cli_dbgmsg("asn1_parse_mscat: failed to read authenticated attribute\n");
		dsize = 1;
		break;
	    }
	    if(!memcmp(deeper.content, OID_contentType, lenof(OID_contentType)))
		content = 0; /* contentType */
	    else if(!memcmp(deeper.content, OID_messageDigest, lenof(OID_messageDigest)))
		content = 1; /* messageDigest */
	    else
		continue;
	    if(asn1_expect_objtype(map, deeper.next, &deep.size, &deeper, 0x31)) { /* set - contents */
		dsize = 1;
		break;
	    }
	    if(deep.size) {
		cli_dbgmsg("asn1_parse_mscat: extra data in authenticated attributes\n");
		dsize = 1;
		break;
	    }

	    if(result & (1<<content)) {
		cli_dbgmsg("asn1_parse_mscat: contentType or messageDigest appear twice\n");
		dsize = 1;
		break;
	    }

	    if(content == 0) { /* contentType */
		if(
		   (!embedded && asn1_expect_obj(map, &deeper.content, &deeper.size, 0x06, lenof(OID_szOID_CTL), OID_szOID_CTL)) || /* cat file */
		   (embedded && asn1_expect_obj(map, &deeper.content, &deeper.size, 0x06, lenof(OID_SPC_INDIRECT_DATA_OBJID), OID_SPC_INDIRECT_DATA_OBJID)) /* embedded cat */
		  ) {
		    dsize = 1;
		    break;
		}
		result |= 1;
	    } else { /* messageDigest */
		if(asn1_expect_objtype(map, deeper.content, &deeper.size, &cobj, 0x04)) {
		    dsize = 1;
		    break;
		}
		if(cobj.size != SHA1_HASH_SIZE) {
		    cli_dbgmsg("asn1_parse_mscat: messageDigest attribute has got the wrong size (%u)\n", cobj.size);
		    dsize = 1;
		    break;
		}
		if(!fmap_need_ptr_once(map, cobj.content, SHA1_HASH_SIZE)) {
		    cli_dbgmsg("asn1_parse_mscat: failed to read authenticated attribute\n");
		    dsize = 1;
		    break;
		}
		memcpy(md, cobj.content, SHA1_HASH_SIZE);
		result |= 2;
	    }
	    if(deeper.size) {
		cli_dbgmsg("asn1_parse_mscat: extra data in authenticated attribute\n");
		dsize = 1;
		break;
	    }
	}
	if(dsize)
	    break;
	if(result != 3) {
	    cli_dbgmsg("asn1_parse_mscat: contentType or messageDigest are missing\n");
	    break;
	}

	if(asn1_expect_algo(map, &asn1.next, &size, lenof(OID_rsaEncryption), OID_rsaEncryption)) /* digestEncryptionAlgorithm == sha1 */
	    break;

	if(asn1_expect_objtype(map, asn1.next, &size, &asn1, 0x04)) /* encryptedDigest */
	    break;
	if(asn1.size > 513) {
	    cli_dbgmsg("asn1_parse_mscat: encryptedDigest too long\n");
	    break;
	}
	if(map_sha1(map, *hashes, *hashes_size, sha1))
	    break;
	if(memcmp(sha1, md, sizeof(sha1))) {
	    cli_dbgmsg("asn1_parse_mscat: messageDigest mismatch\n");
	    break;
	}

	if(!fmap_need_ptr_once(map, attrs, attrs_size)) {
	    cli_dbgmsg("asn1_parse_mscat: failed to read authenticatedAttributes\n");
	    break;
	}

    ctx = cl_hash_init("sha1");
    if (!(ctx))
        break;

	cl_update_hash(ctx, "\x31", 1);
	cl_update_hash(ctx, (void *)(attrs + 1), attrs_size - 1);
	cl_finish_hash(ctx, sha1);

	if(!fmap_need_ptr_once(map, asn1.content, asn1.size)) {
	    cli_dbgmsg("asn1_parse_mscat: failed to read encryptedDigest\n");
	    break;
	}
	if(!(x509 = crtmgr_verify_pkcs7(cmgr, issuer, serial, asn1.content, asn1.size, CLI_SHA1RSA, sha1, VRFY_CODE))) {
	    cli_dbgmsg("asn1_parse_mscat: pkcs7 signature verification failed\n");
	    break;
	}
	message = asn1.content;
	message_size = asn1.size;

	if(!size) {
	    cli_dbgmsg("asn1_parse_mscat: countersignature is missing\n");
	    break;
	}

	if(size && asn1_expect_objtype(map, asn1.next, &size, &asn1, 0xa1)) /* unauthenticatedAttributes */
	    break;

	if(size) {
	    cli_dbgmsg("asn1_parse_mscat: extra data inside signerInfo\n");
	    break;
	}

	size = asn1.size;
	if(asn1_expect_objtype(map, asn1.content, &size, &asn1, 0x30))
	    break;
	if(size) {
	    cli_dbgmsg("asn1_parse_mscat: extra data inside unauthenticatedAttributes\n");
	    break;
	}

	size = asn1.size;
	/* 1.2.840.113549.1.9.6 - counterSignature */
	if(asn1_expect_obj(map, &asn1.content, &size, 0x06, lenof(OID_countersignature), OID_countersignature))
	    break;
	if(asn1_expect_objtype(map, asn1.content, &size, &asn1, 0x31))
	    break;
	if(size) {
	    cli_dbgmsg("asn1_parse_mscat: extra data inside counterSignature\n");
	    break;
	}

	size = asn1.size;
	if(asn1_expect_objtype(map, asn1.content, &size, &asn1, 0x30))
	    break;
	if(size) {
	    cli_dbgmsg("asn1_parse_mscat: extra data inside unauthenticatedAttributes\n");
	    break;
	}

	size = asn1.size;
	if(asn1_expect_obj(map, &asn1.content, &size, 0x02, 1, "\x01")) /* Version = 1*/
	    break;

	if(asn1_expect_objtype(map, asn1.content, &size, &asn1, 0x30)) /* issuerAndSerialNumber */
	    break;

	if(asn1_expect_objtype(map, asn1.content, &asn1.size, &deep, 0x30)) /* issuer */
	    break;
	if(map_sha1(map, deep.content, deep.size, issuer))
	    break;

	if(asn1_expect_objtype(map, deep.next, &asn1.size, &deep, 0x02)) /* serial */
	    break;
	if(map_sha1(map, deep.content, deep.size, serial))
	    break;

	if(asn1.size) {
	    cli_dbgmsg("asn1_parse_mscat: extra data inside countersignature issuer\n");
	    break;
	}

	if(asn1_expect_objtype(map, asn1.next, &size, &asn1, 0x30)) /* digestAlgorithm */
	    break;
	if(asn1_expect_objtype(map, asn1.content, &asn1.size, &deep, 0x06))
	    break;
	if(deep.size != lenof(OID_sha1) && deep.size != lenof(OID_md5)) {
	    cli_dbgmsg("asn1_parse_mscat: wrong digestAlgorithm size\n");
	    break;
	}
	if(!fmap_need_ptr_once(map, deep.content, deep.size)) {
	    cli_dbgmsg("asn1_parse_mscat: failed to read digestAlgorithm OID\n");
	    break;
	}
	if(deep.size == lenof(OID_sha1) && !memcmp(deep.content, OID_sha1, lenof(OID_sha1))) {
	    hashtype = CLI_SHA1RSA;
	    if(map_sha1(map, message, message_size, md))
		break;
	} else if(deep.size == lenof(OID_md5) && !memcmp(deep.content, OID_md5, lenof(OID_md5))) {
	    hashtype = CLI_MD5RSA;
	    if(map_md5(map, message, message_size, md))
		break;
	} else {
	    cli_dbgmsg("asn1_parse_mscat: unknown digest oid in countersignature\n");
	    break;
	}
	if(asn1.size && asn1_expect_obj(map, &deep.next, &asn1.size, 0x05, 0, NULL))
	    break;
	if(asn1.size) {
	    cli_dbgmsg("asn1_parse_mscat: extra data in countersignature oid\n");
	    break;
	}

	attrs = asn1.next;
	if(asn1_expect_objtype(map, asn1.next, &size, &asn1, 0xa0)) /* authenticatedAttributes */
	    break;
	attrs_size = (uint8_t *)(asn1.next) - attrs;
	if(attrs_size < 2) {
	    cli_dbgmsg("asn1_parse_mscat: countersignature authenticatedAttributes are too small\n");
	    break;
	}
	result = 0;
	dsize = asn1.size;
	deep.next = asn1.content;
	while(dsize) {
	    int content;
	    if(asn1_expect_objtype(map, deep.next, &dsize, &deep, 0x30)) { /* attribute */
		dsize = 1;
		break;
	    }
	    if(asn1_expect_objtype(map, deep.content, &deep.size, &deeper, 0x06)) { /* attribute type */
		dsize = 1;
		break;
	    }
	    if(deeper.size != lenof(OID_contentType)) /* lenof(contentType) = lenof(messageDigest) = lenof(signingTime) = 9 */
		continue;

	    if(!fmap_need_ptr_once(map, deeper.content, lenof(OID_contentType))) {
		dsize = 1;
		break;
	    }
	    if(!memcmp(deeper.content, OID_contentType, lenof(OID_contentType)))
		content = 0; /* contentType */
	    else if(!memcmp(deeper.content, OID_messageDigest, lenof(OID_messageDigest)))
		content = 1; /* messageDigest */
	    else if(!memcmp(deeper.content, OID_signingTime, lenof(OID_signingTime)))
		content = 2; /* signingTime */
	    else
		continue;
	    if(result & (1<<content)) {
		cli_dbgmsg("asn1_parse_mscat: duplicate field in countersignature\n");
		dsize = 1;
		break;
	    }
	    result |= (1<<content);
	    if(asn1_expect_objtype(map, deeper.next, &deep.size, &deeper, 0x31)) { /* attribute type */
		dsize = 1;
		break;
	    }
	    if(deep.size) {
		cli_dbgmsg("asn1_parse_mscat: extra data in countersignature value\n");
		dsize = 1;
		break;
	    }
	    deep.size = deeper.size;
	    switch(content) {
	    case 0:  /* contentType = pkcs7-data */
		if(asn1_expect_obj(map, &deeper.content, &deep.size, 0x06, lenof(OID_pkcs7_data), OID_pkcs7_data))
		    deep.size = 1;
		else if(deep.size)
		    cli_dbgmsg("asn1_parse_mscat: extra data in countersignature content-type\n");
		break;
	    case 1:  /* messageDigest */
		if(asn1_expect_obj(map, &deeper.content, &deep.size, 0x04, (hashtype == CLI_SHA1RSA) ? SHA1_HASH_SIZE : 16, md)) {
		    deep.size = 1;
		    cli_dbgmsg("asn1_parse_mscat: countersignature hash mismatch\n");
		} else if(deep.size)
		    cli_dbgmsg("asn1_parse_mscat: extra data in countersignature message-digest\n");
		break;
	    case 2:  /* signingTime */
		{
		    time_t sigdate; /* FIXME shall i use it?! */
		    if(asn1_get_time(map, &deeper.content, &deep.size, &sigdate))
			deep.size = 1;
		    else if(deep.size)
			cli_dbgmsg("asn1_parse_mscat: extra data in countersignature signing-time\n");
		    else if(sigdate < x509->not_before || sigdate > x509->not_after) {
			cli_dbgmsg("asn1_parse_mscat: countersignature timestamp outside cert validity\n");
			deep.size = 1;
		    }
		    break;
		}
	    }
	    if(deep.size) {
		dsize = 1;
		break;
	    }
	}
	if(dsize)
	    break;
	if(result != 7) {
	    cli_dbgmsg("asn1_parse_mscat: some important attributes are missing in countersignature\n");
	    break;
	}

	if(asn1_expect_objtype(map, asn1.next, &size, &asn1, 0x30)) /* digestEncryptionAlgorithm == sha1 */
	    break;
	if(asn1_expect_objtype(map, asn1.content, &asn1.size, &deep, 0x06)) /* digestEncryptionAlgorithm == sha1 */
	    break;
	if(deep.size != lenof(OID_rsaEncryption)) { /* lenof(OID_rsaEncryption) = lenof(OID_sha1WithRSAEncryption) = 9 */
	    cli_dbgmsg("asn1_parse_mscat: wrong digestEncryptionAlgorithm size in countersignature\n");
	    break;
	}
	if(!fmap_need_ptr_once(map, deep.content, lenof(OID_rsaEncryption))) {
	    cli_dbgmsg("asn1_parse_mscat: cannot read digestEncryptionAlgorithm in countersignature\n");
	    break;
	}
	/* rsaEncryption or sha1withRSAEncryption */
	if(memcmp(deep.content, OID_rsaEncryption, lenof(OID_rsaEncryption)) && memcmp(deep.content, OID_sha1WithRSAEncryption, lenof(OID_sha1WithRSAEncryption))) {
	    cli_dbgmsg("asn1_parse_mscat: digestEncryptionAlgorithm in countersignature is not sha1\n");
	    break;
	}
	if(asn1.size && asn1_expect_obj(map, &deep.next, &asn1.size, 0x05, 0, NULL))
	    break;
	if(asn1.size) {
	    cli_dbgmsg("asn1_parse_mscat: extra data in digestEncryptionAlgorithm in countersignature\n");
	    break;
	}

	if(asn1_expect_objtype(map, asn1.next, &size, &asn1, 0x04)) /* encryptedDigest */
	    break;
	if(asn1.size > 513) {
	    cli_dbgmsg("asn1_parse_mscat: countersignature encryptedDigest too long\n");
	    break;
	}
	if(size) {
	    cli_dbgmsg("asn1_parse_mscat: extra data inside countersignature\n");
	    break;
	}
	if(!fmap_need_ptr_once(map, attrs, attrs_size)) {
	    cli_dbgmsg("asn1_parse_mscat: failed to read authenticatedAttributes\n");
	    break;
	}

	if(hashtype == CLI_SHA1RSA) {
        ctx = cl_hash_init("sha1");
        if (!(ctx))
            break;

        cl_update_hash(ctx, "\x31", 1);
        cl_update_hash(ctx, (void *)(attrs + 1), attrs_size - 1);
        cl_finish_hash(ctx, sha1);
	} else {
        ctx = cl_hash_init("md5");
        if (!(ctx))
            break;

        cl_update_hash(ctx, "\x31", 1);
        cl_update_hash(ctx, (void *)(attrs + 1), attrs_size - 1);
        cl_finish_hash(ctx, sha1);
	}

	if(!fmap_need_ptr_once(map, asn1.content, asn1.size)) {
	    cli_dbgmsg("asn1_parse_mscat: failed to read countersignature encryptedDigest\n");
	    break;
	}
	if(!crtmgr_verify_pkcs7(cmgr, issuer, serial, asn1.content, asn1.size, hashtype, sha1, VRFY_TIME)) {
	    cli_dbgmsg("asn1_parse_mscat: pkcs7 countersignature verification failed\n");
	    break;
	}

	cli_dbgmsg("asn1_parse_mscat: catalog successfully parsed\n");
    if (isBlacklisted) {
        return 1;
    }
	return 0;
    } while(0);

    cli_dbgmsg("asn1_parse_mscat: failed to parse catalog\n");
    return 1;
}
php_http_message_parser_state_t php_http_message_parser_parse(php_http_message_parser_t *parser, php_http_buffer_t *buffer, unsigned flags, php_http_message_t **message)
{
	char *str = NULL;
	size_t len = 0;
	size_t cut = 0;

	while (buffer->used || !php_http_message_parser_states[php_http_message_parser_state_is(parser)].need_data) {
#if DBG_PARSER
		fprintf(stderr, "#MP: %s (f: %u, t:%d, l:%zu)\n", 
			php_http_message_parser_state_name(php_http_message_parser_state_is(parser)),
			flags, 
			message && *message ? (*message)->type : -1, 
			buffer->used
		);
		_dpf(0, buffer->data, buffer->used);
#endif

		switch (php_http_message_parser_state_pop(parser))
		{
			case PHP_HTTP_MESSAGE_PARSER_STATE_FAILURE:
				return php_http_message_parser_state_push(parser, 1, PHP_HTTP_MESSAGE_PARSER_STATE_FAILURE);

			case PHP_HTTP_MESSAGE_PARSER_STATE_START:
			{
				char *ptr = buffer->data;

				while (ptr - buffer->data < buffer->used && PHP_HTTP_IS_CTYPE(space, *ptr)) {
					++ptr;
				}

				php_http_buffer_cut(buffer, 0, ptr - buffer->data);

				if (buffer->used) {
					php_http_message_parser_state_push(parser, 1, PHP_HTTP_MESSAGE_PARSER_STATE_HEADER);
				}
				break;
			}

			case PHP_HTTP_MESSAGE_PARSER_STATE_HEADER:
			{
				unsigned header_parser_flags = (flags & PHP_HTTP_MESSAGE_PARSER_CLEANUP) ? PHP_HTTP_HEADER_PARSER_CLEANUP : 0;

				switch (php_http_header_parser_parse(&parser->header, buffer, header_parser_flags, *message ? &(*message)->hdrs : NULL, (php_http_info_callback_t) php_http_message_info_callback, message)) {
					case PHP_HTTP_HEADER_PARSER_STATE_FAILURE:
						return PHP_HTTP_MESSAGE_PARSER_STATE_FAILURE;

					case PHP_HTTP_HEADER_PARSER_STATE_DONE:
						php_http_message_parser_state_push(parser, 1, PHP_HTTP_MESSAGE_PARSER_STATE_HEADER_DONE);
						break;

					default:
						if (buffer->used || !(flags & PHP_HTTP_MESSAGE_PARSER_CLEANUP)) {
							return php_http_message_parser_state_push(parser, 1, PHP_HTTP_MESSAGE_PARSER_STATE_HEADER);
						} else {
							php_http_message_parser_state_push(parser, 1, PHP_HTTP_MESSAGE_PARSER_STATE_HEADER_DONE);
						}
				}
				break;
			}

			case PHP_HTTP_MESSAGE_PARSER_STATE_HEADER_DONE:
			{
				zval h, *h_ptr, *h_loc = NULL, *h_con = NULL, *h_ce;
				zend_bool chunked = 0;
				zend_long content_length = -1;
				zend_string *content_range = NULL;

				/* Content-Range has higher precedence than Content-Length,
				 * and content-length denotes the original length of the entity,
				 * so let's *NOT* remove CR/CL, because that would fundamentally
				 * change the meaning of the whole message
				 */
				if ((h_ptr = php_http_message_header(*message, ZEND_STRL("Transfer-Encoding")))) {
					zend_string *zs = zval_get_string(h_ptr);

					chunked = zend_string_equals_literal(zs, "chunked");
					zend_string_release(zs);

					Z_TRY_ADDREF_P(h_ptr);
					zend_hash_str_update(&(*message)->hdrs, "X-Original-Transfer-Encoding", lenof("X-Original-Transfer-Encoding"), h_ptr);
					zend_hash_str_del(&(*message)->hdrs, "Transfer-Encoding", lenof("Transfer-Encoding"));

					/* reset */
					ZVAL_LONG(&h, 0);
					zend_hash_str_update(&(*message)->hdrs, "Content-Length", lenof("Content-Length"), &h);
				} else if ((h_ptr = php_http_message_header(*message, ZEND_STRL("Content-Length")))) {
					content_length = zval_get_long(h_ptr);
					Z_TRY_ADDREF_P(h_ptr);
					zend_hash_str_update(&(*message)->hdrs, "X-Original-Content-Length", lenof("X-Original-Content-Length"), h_ptr);
				}

				if ((content_range = php_http_message_header_string(*message, ZEND_STRL("Content-Range")))) {
					ZVAL_STR_COPY(&h, content_range);
					zend_hash_str_update(&(*message)->hdrs, "Content-Range", lenof("Content-Range"), &h);
				}

				/* so, if curl sees a 3xx code, a Location header and a Connection:close header
				 * it decides not to read the response body.
				 */
				if ((flags & PHP_HTTP_MESSAGE_PARSER_EMPTY_REDIRECTS)
				&&	(*message)->type == PHP_HTTP_RESPONSE
				&&	(*message)->http.info.response.code/100 == 3
				&&	(h_loc = php_http_message_header(*message, ZEND_STRL("Location")))
				&&	(h_con = php_http_message_header(*message, ZEND_STRL("Connection")))
				) {
					zend_string *con = zval_get_string(h_con);

					if (php_http_match(con->val, "close", PHP_HTTP_MATCH_WORD)) {
						zend_string_release(con);
						php_http_message_parser_state_push(parser, 1, PHP_HTTP_MESSAGE_PARSER_STATE_DONE);
						break;
					}
					zend_string_release(con);
				}

				if ((h_ce = php_http_message_header(*message, ZEND_STRL("Content-Encoding")))) {
					zend_string *ce = zval_get_string(h_ce);

					if (php_http_match(ce->val, "gzip", PHP_HTTP_MATCH_WORD)
					||	php_http_match(ce->val, "x-gzip", PHP_HTTP_MATCH_WORD)
					||	php_http_match(ce->val, "deflate", PHP_HTTP_MATCH_WORD)
					) {
						if (parser->inflate) {
							php_http_encoding_stream_reset(&parser->inflate);
						} else {
							parser->inflate = php_http_encoding_stream_init(NULL, php_http_encoding_stream_get_inflate_ops(), 0);
						}
						Z_TRY_ADDREF_P(h_ce);
						zend_hash_str_update(&(*message)->hdrs, "X-Original-Content-Encoding", lenof("X-Original-Content-Encoding"), h_ce);
						zend_hash_str_del(&(*message)->hdrs, "Content-Encoding", lenof("Content-Encoding"));
					}
					zend_string_release(ce);
				}

				if ((flags & PHP_HTTP_MESSAGE_PARSER_DUMB_BODIES)) {
					php_http_message_parser_state_push(parser, 1, PHP_HTTP_MESSAGE_PARSER_STATE_BODY_DUMB);
				} else {
					if (chunked) {
						parser->dechunk = php_http_encoding_stream_init(parser->dechunk, php_http_encoding_stream_get_dechunk_ops(), 0);
						php_http_message_parser_state_push(parser, 1, PHP_HTTP_MESSAGE_PARSER_STATE_BODY_CHUNKED);
						break;
					}

					if (content_range) {
						ulong total = 0, start = 0, end = 0;

						if (!strncasecmp(content_range->val, "bytes", lenof("bytes"))
						&& (	content_range->val[lenof("bytes")] == ':'
							||	content_range->val[lenof("bytes")] == ' '
							||	content_range->val[lenof("bytes")] == '='
							)
						) {
							char *total_at = NULL, *end_at = NULL;
							char *start_at = content_range->val + sizeof("bytes");

							start = strtoul(start_at, &end_at, 10);
							if (end_at) {
								end = strtoul(end_at + 1, &total_at, 10);
								if (total_at && strncmp(total_at + 1, "*", 1)) {
									total = strtoul(total_at + 1, NULL, 10);
								}

								if (end >= start && (!total || end <= total)) {
									parser->body_length = end + 1 - start;
									php_http_message_parser_state_push(parser, 1, !parser->body_length?PHP_HTTP_MESSAGE_PARSER_STATE_BODY_DONE:PHP_HTTP_MESSAGE_PARSER_STATE_BODY_LENGTH);
									zend_string_release(content_range);
									break;
								}
							}
						}

						zend_string_release(content_range);
					}

					if (content_length >= 0) {
						parser->body_length = content_length;
						php_http_message_parser_state_push(parser, 1, !parser->body_length?PHP_HTTP_MESSAGE_PARSER_STATE_BODY_DONE:PHP_HTTP_MESSAGE_PARSER_STATE_BODY_LENGTH);
						break;
					}

					if ((*message)->type == PHP_HTTP_REQUEST) {
						php_http_message_parser_state_push(parser, 1, PHP_HTTP_MESSAGE_PARSER_STATE_DONE);
					} else {
						php_http_message_parser_state_push(parser, 1, PHP_HTTP_MESSAGE_PARSER_STATE_BODY_DUMB);
					}
				}
				break;
			}

			case PHP_HTTP_MESSAGE_PARSER_STATE_BODY:
			{
				if (len) {
					if (parser->inflate) {
						char *dec_str = NULL;
						size_t dec_len;

						if (SUCCESS != php_http_encoding_stream_update(parser->inflate, str, len, &dec_str, &dec_len)) {
							return php_http_message_parser_state_push(parser, 1, PHP_HTTP_MESSAGE_PARSER_STATE_FAILURE);
						}

						if (str != buffer->data) {
							PTR_FREE(str);
						}
						str = dec_str;
						len = dec_len;
					}

					php_stream_write(php_http_message_body_stream((*message)->body), str, len);
				}

				if (cut) {
					php_http_buffer_cut(buffer, 0, cut);
				}

				if (str != buffer->data) {
					PTR_FREE(str);
				}

				str = NULL;
				len = 0;
				cut = 0;
				break;
			}

			case PHP_HTTP_MESSAGE_PARSER_STATE_BODY_DUMB:
			{
				str = buffer->data;
				len = buffer->used;
				cut = len;

				php_http_message_parser_state_push(parser, 2, PHP_HTTP_MESSAGE_PARSER_STATE_BODY_DONE, PHP_HTTP_MESSAGE_PARSER_STATE_BODY);
				break;
			}

			case PHP_HTTP_MESSAGE_PARSER_STATE_BODY_LENGTH:
			{
				len = MIN(parser->body_length, buffer->used);
				str = buffer->data;
				cut = len;

				parser->body_length -= len;

				php_http_message_parser_state_push(parser, 2, !parser->body_length?PHP_HTTP_MESSAGE_PARSER_STATE_BODY_DONE:PHP_HTTP_MESSAGE_PARSER_STATE_BODY_LENGTH, PHP_HTTP_MESSAGE_PARSER_STATE_BODY);
				break;
			}

			case PHP_HTTP_MESSAGE_PARSER_STATE_BODY_CHUNKED:
			{
				/*
				 * - pass available data through the dechunk stream
				 * - pass decoded data along
				 * - if stream zeroed:
				 * 	Y:	- cut processed string out of buffer, but leave length of unprocessed dechunk stream data untouched
				 * 		- body done
				 * 	N:	- parse ahaed
				 */
				char *dec_str = NULL;
				size_t dec_len;

				if (SUCCESS != php_http_encoding_stream_update(parser->dechunk, buffer->data, buffer->used, &dec_str, &dec_len)) {
					return PHP_HTTP_MESSAGE_PARSER_STATE_FAILURE;
				}

				str = dec_str;
				len = dec_len;

				if (php_http_encoding_stream_done(parser->dechunk)) {
					cut = buffer->used - PHP_HTTP_BUFFER(parser->dechunk->ctx)->used;
					php_http_message_parser_state_push(parser, 2, PHP_HTTP_MESSAGE_PARSER_STATE_BODY_DONE, PHP_HTTP_MESSAGE_PARSER_STATE_BODY);
				} else {
					cut = buffer->used;
					php_http_message_parser_state_push(parser, 2, PHP_HTTP_MESSAGE_PARSER_STATE_BODY_CHUNKED, PHP_HTTP_MESSAGE_PARSER_STATE_BODY);
				}
				break;
			}

			case PHP_HTTP_MESSAGE_PARSER_STATE_BODY_DONE:
			{
				php_http_message_parser_state_push(parser, 1, PHP_HTTP_MESSAGE_PARSER_STATE_DONE);

				if (parser->dechunk && parser->dechunk->ctx) {
					char *dec_str = NULL;
					size_t dec_len;

					if (SUCCESS != php_http_encoding_stream_finish(parser->dechunk, &dec_str, &dec_len)) {
						return php_http_message_parser_state_push(parser, 1, PHP_HTTP_MESSAGE_PARSER_STATE_FAILURE);
					}
					php_http_encoding_stream_dtor(parser->dechunk);

					if (dec_str && dec_len) {
						str = dec_str;
						len = dec_len;
						cut = 0;
						php_http_message_parser_state_push(parser, 2, PHP_HTTP_MESSAGE_PARSER_STATE_UPDATE_CL, PHP_HTTP_MESSAGE_PARSER_STATE_BODY);
					}
				}

				break;
			}

			case PHP_HTTP_MESSAGE_PARSER_STATE_UPDATE_CL:
			{
				zval zcl;

				ZVAL_LONG(&zcl, php_http_message_body_size((*message)->body));
				zend_hash_str_update(&(*message)->hdrs, "Content-Length", lenof("Content-Length"), &zcl);
				break;
			}

			case PHP_HTTP_MESSAGE_PARSER_STATE_DONE:
			{
				char *ptr = buffer->data;

				while (ptr - buffer->data < buffer->used && PHP_HTTP_IS_CTYPE(space, *ptr)) {
					++ptr;
				}

				php_http_buffer_cut(buffer, 0, ptr - buffer->data);
				
				if (!(flags & PHP_HTTP_MESSAGE_PARSER_GREEDY)) {
					return PHP_HTTP_MESSAGE_PARSER_STATE_DONE;
				}
				break;
			}
		}
	}

	return php_http_message_parser_state_is(parser);
}
예제 #19
0
파일: fcgi-utils.c 프로젝트: s3v3ns/sx
void handle_request(worker_type_t wtype) {
    const char *param, *p_method, *p_uri;
    char *argp;
    unsigned int plen;
    int cluster_readonly = 0, s2sreq = 0;

    if(sx_hashfs_cluster_get_mode(hashfs, &cluster_readonly)) {
        CRIT("Failed to get cluster operating mode");
        quit_errmsg(500, "Internal error: failed to check cluster operating mode");
    }

    if(sx_hashfs_distcheck(hashfs) < 0) {
	CRIT("Failed to reload distribution");
	quit_errmsg(503, "Internal error: failed to load distribution");
    }

    if(sx_hashfs_is_orphan(hashfs))
	quit_errmsg(410, "This node is no longer a cluster member");

    msg_new_id();
    verb = VERB_UNSUP;
    p_method = FCGX_GetParam("REQUEST_METHOD", envp);
    if(p_method) {
	plen = strlen(p_method);
	switch(plen) {
	case 3:
	    if(!memcmp(p_method, "GET", 4))
		verb = VERB_GET;
	    else if(!memcmp(p_method, "PUT", 4))
		verb = VERB_PUT;
	    break;
	case 4:
	    if(!memcmp(p_method, "HEAD", 5))
		verb = VERB_HEAD;
	    else if(!memcmp(p_method, "POST", 5))
		verb = VERB_POST;
	    break;
	case 6:
	    if(!memcmp(p_method, "DELETE", 7))
		verb = VERB_DELETE;
	    break;
	case 7:
	    if(!memcmp(p_method, "OPTIONS", 8)) {
		CGI_PUTS("Allow: GET,HEAD,OPTIONS,PUT,DELETE\r\nContent-Length: 0\r\n\r\n");
		return;
	    }
	    break;
	}
    }
    if(verb == VERB_UNSUP)
	quit_errmsg(405, "Method Not Allowed");

    if(content_len()<0 || (verb != VERB_PUT && content_len()))
	quit_errmsg(400, "Invalid Content-Length: must be positive and method must be PUT");

    p_uri = param = FCGX_GetParam("REQUEST_URI", envp);
    if(!p_uri)
	quit_errmsg(400, "No URI provided");
    plen = strlen(p_uri);
    if(*p_uri != '/')
	quit_errmsg(400, "URI must start with /");
    if(plen > sizeof(reqbuf) - 1)
	quit_errmsg(414, "URL too long: request line must be <8k");

    do {
	param++;
	plen--;
    } while(*param == '/');

    if(!strncmp(param, ".s2s/", lenof(".s2s/"))) {
	param += lenof(".s2s/");
	plen -= lenof(".s2s/");
	while(*param == '/') {
	    param++;
	    plen--;
	}
	s2sreq = 1;
    }
    if(wtype == WORKER_S2S && !s2sreq)
	WARN("Misconfiguration detected. Please make sure your restricted-socket config option is properly set.");
    /* FIXME: we could detect the opposite kind of mismatch
     * at the cost of extra complications in the wtype definition
     * I prefer to privilege simplicity at this point */

    memcpy(reqbuf, param, plen+1);
    argp = memchr(reqbuf, '?', plen);
    nargs = 0;
    if(argp) {
	unsigned int argslen = plen - (argp - reqbuf);
	plen = argp - reqbuf;
	do {
	    *argp = '\0';
	    argp++;
	    argslen--;
	} while(*argp == '?');
	if(!argslen)
	    argp = NULL;
	else {
	    do {
		char *nextarg;
		if(nargs >= MAX_ARGS)
		    quit_errmsg(414, "Too many parameters");
		nextarg = memchr(argp, '&', argslen);
		if(nextarg) {
		    do {
			*nextarg = '\0';
			nextarg++;
		    } while(*nextarg == '&');
		}
		if(*argp) {
		    if(!(args[nargs] = inplace_urldecode(argp, 0, 0, NULL, 1)))
			quit_errmsg(400, "Invalid URL encoding");
		    if(sxi_utf8_validate_len(args[nargs]) < 0)
			quit_errmsg(400, "Parameters with invalid utf-8 encoding");
		    nargs++;
		}
		argslen -= nextarg - argp;
		argp = nextarg;
	    } while (argp);
	}
    }

    while(plen && reqbuf[plen-1] == '/') {
	plen--;
	reqbuf[plen] = '\0';
    }

    path = memchr(reqbuf, '/', plen);
    if(path) {
	do {
	    *path = '\0';
	    path ++;
	} while(*path == '/');
	if(!*path)
	    path = NULL;
    }
    volume = *reqbuf ? reqbuf : NULL;

    int forbidden = 0;
    if((volume && !inplace_urldecode(volume, '/', 0, &forbidden, 0)) || (path && !inplace_urldecode(path, '/', '/', &forbidden, 0))) {
        if (forbidden)
            quit_errmsg(400, "Volume or path with forbidden %2f or %00");
        else
            quit_errmsg(400, "Invalid URL encoding");
    }

    int vlen = volume ? sxi_utf8_validate_len(volume) : 0;
    int flen = path ? strlen(path) : 0;

    if (vlen < 0 || flen < 0)
       quit_errmsg(400, "URL with invalid utf-8 encoding");

    if (is_reserved()) {
        /* No UTF8/url-encoding used on reserved volumes, allow higher limit.
         * Otherwise we hit the 1024 limit with batch requests already */
        if (path && strlen(path) > SXLIMIT_MAX_FILENAME_LEN * 3) {
            msg_set_reason("Path too long: filename must be <%d bytes (%ld)",
                           SXLIMIT_MAX_FILENAME_LEN*3+ 1, strlen(path));
            quit_errmsg(414, msg_get_reason());
        }
    } else {
        if (flen > SXLIMIT_MAX_FILENAME_LEN) {
            msg_set_reason("Path too long: filename must be <%d bytes (%d)",
                           SXLIMIT_MAX_FILENAME_LEN + 1, flen);
            quit_errmsg(414, msg_get_reason());
        }
    }

    if (volume && strlen(volume) > SXLIMIT_MAX_VOLNAME_LEN) {
        msg_set_reason("Volume name too long: must be <= %d bytes", SXLIMIT_MAX_VOLNAME_LEN);
        quit_errmsg(414, msg_get_reason());
    }

    body_ctx = sxi_md_init();
    if (!body_ctx || !sxi_sha1_init(body_ctx))
	quit_errmsg(500, "Failed to initialize crypto engine");
    hmac_ctx = sxi_hmac_sha1_init();
    if (!hmac_ctx)
        quit_errmsg(503, "Cannot initialize crypto library");

    authed = AUTH_NOTAUTH;
    role = PRIV_NONE;


    /* Begin auth check */
    uint8_t buf[AUTHTOK_BIN_LEN], key[AUTH_KEY_LEN];
    unsigned int blen = sizeof(buf);
    time_t reqdate, now;

    param = FCGX_GetParam("HTTP_AUTHORIZATION", envp);
    if(!param || strlen(param) != lenof("SKY ") + AUTHTOK_ASCII_LEN || strncmp(param, "SKY ", 4)) {
	if(volume) {
	    send_authreq();
	    return;
	}
	quit_home();
    }

    if(sxi_b64_dec_core(param+4, buf, &blen) || blen != sizeof(buf)) {
	send_authreq();
	return;
    }

    memcpy(user, buf, sizeof(user));
    memcpy(rhmac, buf+20, sizeof(rhmac));

    if(sx_hashfs_get_user_info(hashfs, user, &uid, key, &role, NULL, &user_quota) != OK) /* no such user */ {
	DEBUG("No such user: %s", param+4);
	send_authreq();
	return;
    }
    DEBUG("Request from uid %lld", (long long)uid);
    if(cluster_readonly && (verb == VERB_PUT || verb == VERB_DELETE) && !has_priv(PRIV_CLUSTER) && !has_priv(PRIV_ADMIN))
        quit_errmsg(503, "Cluster is in read-only mode");

    if(s2sreq && !has_priv(PRIV_CLUSTER)) {
	send_authreq();
	return;
    }

    if(!sxi_hmac_sha1_init_ex(hmac_ctx, key, sizeof(key))) {
	WARN("hmac_init failed");
	quit_errmsg(500, "Failed to initialize crypto engine");
    }

    if(!sxi_hmac_sha1_update_str(hmac_ctx, p_method))
	quit_errmsg(500, "Crypto error authenticating the request");

    if(!sxi_hmac_sha1_update_str(hmac_ctx, p_uri+1))
	quit_errmsg(500, "Crypto error authenticating the request");

    param = FCGX_GetParam("HTTP_DATE", envp);
    if(!param)
	quit_errmsg(400, "Missing Date: header");
    if(httpdate_to_time_t(param, &reqdate))
	quit_errmsg(400, "Date header in wrong format");
    now = time(NULL);
    if(reqdate < now - MAX_CLOCK_DRIFT * 60 || reqdate > now + MAX_CLOCK_DRIFT * 60) {
	CGI_PUTS("WWW-Authenticate: SKY realm=\"SXCLOCK\"\r\n");
	quit_errmsg(401, "Client clock drifted more than "STRIFY(MAX_CLOCK_DRIFT)" minutes");
    }
    if(!sxi_hmac_sha1_update_str(hmac_ctx, param))
	quit_errmsg(500, "Crypto error authenticating the request");

    if(!content_len()) {
	/* If no body is present, complete authentication now */
	uint8_t chmac[20];
	unsigned int chmac_len = 20;
	if(!sxi_hmac_sha1_update_str(hmac_ctx, "da39a3ee5e6b4b0d3255bfef95601890afd80709"))
	    quit_errmsg(500, "Crypto error authenticating the request");
	if(!sxi_hmac_sha1_final(hmac_ctx, chmac, &chmac_len))
	    quit_errmsg(500, "Crypto error authenticating the request");
	if(!hmac_compare(chmac, rhmac, sizeof(rhmac))) {
	    authed = AUTH_OK;
	} else {
	    /* WARN("auth mismatch"); */
	    send_authreq();
	    return;
	}
    } else /* Otherwise set it as pending */
	authed = AUTH_BODYCHECK;

    if(has_priv(PRIV_CLUSTER) && sx_hashfs_uses_secure_proto(hashfs) != is_https() &&
       !sx_storage_is_bare(hashfs)) {
        /* programmed nodes: must obey cluster SSL mode
         * unprogrammed nodes: can use SSL instead of non-SSL,
         *  it is the cluster's responsibility to initiate programming via SSL,
         *  as the unprogrammed node would accept both         *
         * */
        WARN("hashfs use-ssl: %d, https: %d, is_bare: %d",
              sx_hashfs_uses_secure_proto(hashfs), is_https(),
              sx_storage_is_bare(hashfs));
	quit_errmsg(403, sx_hashfs_uses_secure_proto(hashfs) ? "Cluster operations require SECURE mode" : "Cluster operations require INSECURE mode");
    }

    if(!volume)
	cluster_ops();
    else if(!path)
	volume_ops();
    else
	file_ops();

    if(authed == AUTH_BODYCHECKING)
	DEBUG("Bad request signature");

    sxi_hmac_sha1_cleanup(&hmac_ctx);
    sxi_md_cleanup(&body_ctx);
}
예제 #20
0
int do_eventsel_loop(HANDLE other_event)
{
	int n, nhandles, nallhandles, netindex, otherindex;
	long next, ticks;
	HANDLE *handles;
	SOCKET *sklist;
	int skcount;
	long now = GETTICKCOUNT();
	static int timeoutCount = 0;

	if (sk_isClosed()) {
		return -1;
	}

	if (run_timers(now, &next)) {
		ticks = next - GETTICKCOUNT();
		if (ticks < 0) ticks = 0;  /* just in case */
	} else {
		ticks = INFINITE;
	}

	if (ticks < 0 || ticks > 100) ticks = 100;

	handles = handle_get_events(&nhandles);
	handles = sresize(handles, nhandles+2, HANDLE);
	nallhandles = nhandles;

	if (netevent != INVALID_HANDLE_VALUE)
		handles[netindex = nallhandles++] = netevent;
	else
		netindex = -1;
	if (other_event != INVALID_HANDLE_VALUE)
		handles[otherindex = nallhandles++] = other_event;
	else
		otherindex = -1;

	n = WaitForMultipleObjects(nallhandles, handles, FALSE, ticks);

	if (STATUS_TIMEOUT == n) {
		sfree(handles);
		++timeoutCount;
		return timeoutCount > 50 ? -1 : 0;
	}
	timeoutCount = 0;

	if ((unsigned)(n - WAIT_OBJECT_0) < (unsigned)nhandles) {
		handle_got_event(handles[n - WAIT_OBJECT_0]);
	} else if (netindex >= 0 && n == WAIT_OBJECT_0 + netindex) {
		WSANETWORKEVENTS things;
		SOCKET socket;
		extern SOCKET first_socket(int *), next_socket(int *);
		extern int select_result(WPARAM, LPARAM);
		int i, socketstate;

		/*
		* We must not call select_result() for any socket
		* until we have finished enumerating within the
		* tree. This is because select_result() may close
		* the socket and modify the tree.
		*/
		/* Count the active sockets. */
		i = 0;		
		for (socket = first_socket(&socketstate);
			socket != INVALID_SOCKET;
			socket = next_socket(&socketstate)) i++;

		/* Expand the buffer if necessary. */
		sklist = snewn(i, SOCKET);

		/* Retrieve the sockets into sklist. */
		skcount = 0;
		for (socket = first_socket(&socketstate);
			socket != INVALID_SOCKET;
			socket = next_socket(&socketstate)) {
				sklist[skcount++] = socket;
		}

		/* Now we're done enumerating; go through the list. */
		for (i = 0; i < skcount; i++) {
			WPARAM wp;
			socket = sklist[i];
			wp = (WPARAM) socket;
			if (!p_WSAEnumNetworkEvents(socket, NULL, &things)) {
				static const struct { int bit, mask; } eventtypes[] = {
					{FD_CONNECT_BIT, FD_CONNECT},
					{FD_READ_BIT, FD_READ},
					{FD_CLOSE_BIT, FD_CLOSE},
					{FD_OOB_BIT, FD_OOB},
					{FD_WRITE_BIT, FD_WRITE},
					{FD_ACCEPT_BIT, FD_ACCEPT},
				};
				int e;

				noise_ultralight(socket);
				noise_ultralight(things.lNetworkEvents);

				for (e = 0; e < lenof(eventtypes); e++)
					if (things.lNetworkEvents & eventtypes[e].mask) {
						LPARAM lp;
						int err = things.iErrorCode[eventtypes[e].bit];
						lp = WSAMAKESELECTREPLY(eventtypes[e].mask, err);
						select_result(wp, lp);
					}
			}
		}

		sfree(sklist);
	}

	sfree(handles);

	if (n == WAIT_TIMEOUT) {
		now = next;
	} else {
		now = GETTICKCOUNT();
	}

	if (otherindex >= 0 && n == WAIT_OBJECT_0 + otherindex)
		return 1;

	return 0;
}
예제 #21
0
파일: winnet.c 프로젝트: lalbornoz/FySTY
SockAddr *sk_namelookup(const char *host, char **canonicalname,
                        int address_family)
{
    SockAddr *ret = snew(SockAddr);
    unsigned long a;
    char realhost[8192];
    int hint_family;

    /* Default to IPv4. */
    hint_family = (address_family == ADDRTYPE_IPV4 ? AF_INET :
#ifndef NO_IPV6
		   address_family == ADDRTYPE_IPV6 ? AF_INET6 :
#endif
		   AF_UNSPEC);

    /* Clear the structure and default to IPv4. */
    memset(ret, 0, sizeof(SockAddr));
#ifndef NO_IPV6
    ret->ais = NULL;
#endif
    ret->namedpipe = false;
    ret->addresses = NULL;
    ret->resolved = false;
    ret->refcount = 1;
    *realhost = '\0';

    if ((a = p_inet_addr(host)) == (unsigned long) INADDR_NONE) {
	struct hostent *h = NULL;
	int err = 0;
#ifndef NO_IPV6
	/*
	 * Use getaddrinfo when it's available
	 */
	if (p_getaddrinfo) {
	    struct addrinfo hints;
	    memset(&hints, 0, sizeof(hints));
	    hints.ai_family = hint_family;
	    hints.ai_flags = AI_CANONNAME;
            {
                /* strip [] on IPv6 address literals */
                char *trimmed_host = host_strduptrim(host);
                err = p_getaddrinfo(trimmed_host, NULL, &hints, &ret->ais);
                sfree(trimmed_host);
            }
	    if (err == 0)
		ret->resolved = true;
	} else
#endif
	{
	    /*
	     * Otherwise use the IPv4-only gethostbyname...
	     * (NOTE: we don't use gethostbyname as a fallback!)
	     */
	    if ( (h = p_gethostbyname(host)) )
		ret->resolved = true;
	    else
		err = p_WSAGetLastError();
	}

	if (!ret->resolved) {
	    ret->error = (err == WSAENETDOWN ? "Network is down" :
			  err == WSAHOST_NOT_FOUND ? "Host does not exist" :
			  err == WSATRY_AGAIN ? "Host not found" :
#ifndef NO_IPV6
			  p_getaddrinfo&&p_gai_strerror ? p_gai_strerror(err) :
#endif
			  "gethostbyname: unknown error");
	} else {
	    ret->error = NULL;

#ifndef NO_IPV6
	    /* If we got an address info use that... */
	    if (ret->ais) {
		/* Are we in IPv4 fallback mode? */
		/* We put the IPv4 address into the a variable so we can further-on use the IPv4 code... */
		if (ret->ais->ai_family == AF_INET)
		    memcpy(&a,
			   (char *) &((SOCKADDR_IN *) ret->ais->
				      ai_addr)->sin_addr, sizeof(a));

		if (ret->ais->ai_canonname)
		    strncpy(realhost, ret->ais->ai_canonname, lenof(realhost));
		else
		    strncpy(realhost, host, lenof(realhost));
	    }
	    /* We used the IPv4-only gethostbyname()... */
	    else
#endif
	    {
		int n;
		for (n = 0; h->h_addr_list[n]; n++);
		ret->addresses = snewn(n, unsigned long);
		ret->naddresses = n;
		for (n = 0; n < ret->naddresses; n++) {
		    memcpy(&a, h->h_addr_list[n], sizeof(a));
		    ret->addresses[n] = p_ntohl(a);
		}
		memcpy(&a, h->h_addr, sizeof(a));
		/* This way we are always sure the h->h_name is valid :) */
		strncpy(realhost, h->h_name, sizeof(realhost));
	    }
	}
    } else {
예제 #22
0
파일: settings.c 프로젝트: emonkak/putty
void save_open_settings(void *sesskey, Config *cfg)
{
    int i;
    char *p;

    write_setting_i(sesskey, "Present", 1);
    write_setting_s(sesskey, "HostName", cfg->host);
    write_setting_filename(sesskey, "LogFileName", cfg->logfilename);
    write_setting_i(sesskey, "LogType", cfg->logtype);
    write_setting_i(sesskey, "LogFileClash", cfg->logxfovr);
    write_setting_i(sesskey, "LogFlush", cfg->logflush);
    write_setting_i(sesskey, "SSHLogOmitPasswords", cfg->logomitpass);
    write_setting_i(sesskey, "SSHLogOmitData", cfg->logomitdata);
    p = "raw";
    {
	const Backend *b = backend_from_proto(cfg->protocol);
	if (b)
	    p = b->name;
    }
    write_setting_s(sesskey, "Protocol", p);
    write_setting_i(sesskey, "PortNumber", cfg->port);
    /* The CloseOnExit numbers are arranged in a different order from
     * the standard FORCE_ON / FORCE_OFF / AUTO. */
    write_setting_i(sesskey, "CloseOnExit", (cfg->close_on_exit+2)%3);
    write_setting_i(sesskey, "WarnOnClose", !!cfg->warn_on_close);
    write_setting_i(sesskey, "PingInterval", cfg->ping_interval / 60);	/* minutes */
    write_setting_i(sesskey, "PingIntervalSecs", cfg->ping_interval % 60);	/* seconds */
    write_setting_i(sesskey, "TCPNoDelay", cfg->tcp_nodelay);
    write_setting_i(sesskey, "TCPKeepalives", cfg->tcp_keepalives);
    write_setting_s(sesskey, "TerminalType", cfg->termtype);
    write_setting_s(sesskey, "TerminalSpeed", cfg->termspeed);
    wmap(sesskey, "TerminalModes", cfg->ttymodes, lenof(cfg->ttymodes));

    /* Address family selection */
    write_setting_i(sesskey, "AddressFamily", cfg->addressfamily);

    /* proxy settings */
    write_setting_s(sesskey, "ProxyExcludeList", cfg->proxy_exclude_list);
    write_setting_i(sesskey, "ProxyDNS", (cfg->proxy_dns+2)%3);
    write_setting_i(sesskey, "ProxyLocalhost", cfg->even_proxy_localhost);
    write_setting_i(sesskey, "ProxyMethod", cfg->proxy_type);
    write_setting_s(sesskey, "ProxyHost", cfg->proxy_host);
    write_setting_i(sesskey, "ProxyPort", cfg->proxy_port);
    write_setting_s(sesskey, "ProxyUsername", cfg->proxy_username);
    write_setting_s(sesskey, "ProxyPassword", cfg->proxy_password);
    write_setting_s(sesskey, "ProxyTelnetCommand", cfg->proxy_telnet_command);
    wmap(sesskey, "Environment", cfg->environmt, lenof(cfg->environmt));
    write_setting_s(sesskey, "UserName", cfg->username);
    write_setting_i(sesskey, "UserNameFromEnvironment", cfg->username_from_env);
    write_setting_s(sesskey, "LocalUserName", cfg->localusername);
    write_setting_i(sesskey, "NoPTY", cfg->nopty);
    write_setting_i(sesskey, "Compression", cfg->compression);
    write_setting_i(sesskey, "TryAgent", cfg->tryagent);
    write_setting_i(sesskey, "AgentFwd", cfg->agentfwd);
    write_setting_i(sesskey, "GssapiFwd", cfg->gssapifwd);
    write_setting_i(sesskey, "ChangeUsername", cfg->change_username);
    wprefs(sesskey, "Cipher", ciphernames, CIPHER_MAX,
	   cfg->ssh_cipherlist);
    wprefs(sesskey, "KEX", kexnames, KEX_MAX, cfg->ssh_kexlist);
    write_setting_i(sesskey, "RekeyTime", cfg->ssh_rekey_time);
    write_setting_s(sesskey, "RekeyBytes", cfg->ssh_rekey_data);
    write_setting_i(sesskey, "SshNoAuth", cfg->ssh_no_userauth);
    write_setting_i(sesskey, "SshBanner", cfg->ssh_show_banner);
    write_setting_i(sesskey, "AuthTIS", cfg->try_tis_auth);
    write_setting_i(sesskey, "AuthKI", cfg->try_ki_auth);
    write_setting_i(sesskey, "AuthGSSAPI", cfg->try_gssapi_auth);
#ifndef NO_GSSAPI
    wprefs(sesskey, "GSSLibs", gsslibkeywords, ngsslibs,
	   cfg->ssh_gsslist);
    write_setting_filename(sesskey, "GSSCustom", cfg->ssh_gss_custom);
#endif
    write_setting_i(sesskey, "SshNoShell", cfg->ssh_no_shell);
    write_setting_i(sesskey, "SshProt", cfg->sshprot);
    write_setting_s(sesskey, "LogHost", cfg->loghost);
    write_setting_i(sesskey, "SSH2DES", cfg->ssh2_des_cbc);
    write_setting_filename(sesskey, "PublicKeyFile", cfg->keyfile);
    write_setting_s(sesskey, "RemoteCommand", cfg->remote_cmd);
    write_setting_i(sesskey, "RFCEnviron", cfg->rfc_environ);
    write_setting_i(sesskey, "PassiveTelnet", cfg->passive_telnet);
    write_setting_i(sesskey, "BackspaceIsDelete", cfg->bksp_is_delete);
    write_setting_i(sesskey, "RXVTHomeEnd", cfg->rxvt_homeend);
    write_setting_i(sesskey, "LinuxFunctionKeys", cfg->funky_type);
    write_setting_i(sesskey, "NoApplicationKeys", cfg->no_applic_k);
    write_setting_i(sesskey, "NoApplicationCursors", cfg->no_applic_c);
    write_setting_i(sesskey, "NoMouseReporting", cfg->no_mouse_rep);
    write_setting_i(sesskey, "NoRemoteResize", cfg->no_remote_resize);
    write_setting_i(sesskey, "NoAltScreen", cfg->no_alt_screen);
    write_setting_i(sesskey, "NoRemoteWinTitle", cfg->no_remote_wintitle);
    write_setting_i(sesskey, "RemoteQTitleAction", cfg->remote_qtitle_action);
    write_setting_i(sesskey, "NoDBackspace", cfg->no_dbackspace);
    write_setting_i(sesskey, "NoRemoteCharset", cfg->no_remote_charset);
    write_setting_i(sesskey, "ApplicationCursorKeys", cfg->app_cursor);
    write_setting_i(sesskey, "ApplicationKeypad", cfg->app_keypad);
    write_setting_i(sesskey, "NetHackKeypad", cfg->nethack_keypad);
    write_setting_i(sesskey, "AltF4", cfg->alt_f4);
    write_setting_i(sesskey, "AltSpace", cfg->alt_space);
    write_setting_i(sesskey, "AltOnly", cfg->alt_only);
    write_setting_i(sesskey, "AltMetaBit", cfg->alt_metabit);
    write_setting_i(sesskey, "CtrlTabSwitch", cfg->ctrl_tab_switch);
    write_setting_i(sesskey, "ComposeKey", cfg->compose_key);
    write_setting_i(sesskey, "CtrlAltKeys", cfg->ctrlaltkeys);
    write_setting_i(sesskey, "RightAltKey", cfg->rightaltkey);
    write_setting_i(sesskey, "TelnetKey", cfg->telnet_keyboard);
    write_setting_i(sesskey, "TelnetRet", cfg->telnet_newline);
    write_setting_i(sesskey, "LocalEcho", cfg->localecho);
    write_setting_i(sesskey, "LocalEdit", cfg->localedit);
    write_setting_s(sesskey, "Answerback", cfg->answerback);
    write_setting_i(sesskey, "AlwaysOnTop", cfg->alwaysontop);
    write_setting_i(sesskey, "FullScreenOnAltEnter", cfg->fullscreenonaltenter);
    write_setting_i(sesskey, "HideMousePtr", cfg->hide_mouseptr);
    write_setting_i(sesskey, "SunkenEdge", cfg->sunken_edge);
    write_setting_filename(sesskey, "IconFile", cfg->iconfile);
    write_setting_i(sesskey, "WindowBorder", cfg->window_border);
    write_setting_i(sesskey, "CurType", cfg->cursor_type);
    write_setting_i(sesskey, "BlinkCur", cfg->blink_cur);
    write_setting_i(sesskey, "Beep", cfg->beep);
    write_setting_i(sesskey, "BeepInd", cfg->beep_ind);
    write_setting_filename(sesskey, "BellWaveFile", cfg->bell_wavefile);
    write_setting_i(sesskey, "BellOverload", cfg->bellovl);
    write_setting_i(sesskey, "BellOverloadN", cfg->bellovl_n);
    write_setting_i(sesskey, "BellOverloadT", cfg->bellovl_t
#ifdef PUTTY_UNIX_H
		    * 1000
#endif
		    );
    write_setting_i(sesskey, "BellOverloadS", cfg->bellovl_s
#ifdef PUTTY_UNIX_H
		    * 1000
#endif
		    );
    write_setting_i(sesskey, "ScrollbackLines", cfg->savelines);
    write_setting_i(sesskey, "DECOriginMode", cfg->dec_om);
    write_setting_i(sesskey, "AutoWrapMode", cfg->wrap_mode);
    write_setting_i(sesskey, "LFImpliesCR", cfg->lfhascr);
    write_setting_i(sesskey, "CRImpliesLF", cfg->crhaslf);
    write_setting_i(sesskey, "DisableArabicShaping", cfg->arabicshaping);
    write_setting_i(sesskey, "DisableBidi", cfg->bidi);
    write_setting_i(sesskey, "WinNameAlways", cfg->win_name_always);
    write_setting_s(sesskey, "WinTitle", cfg->wintitle);
    write_setting_i(sesskey, "TermWidth", cfg->width);
    write_setting_i(sesskey, "TermHeight", cfg->height);
    write_setting_i(sesskey, "TermX", cfg->x);
    write_setting_i(sesskey, "TermY", cfg->y);
    write_setting_fontspec(sesskey, "Font", cfg->font);
    write_setting_i(sesskey, "FontQuality", cfg->font_quality);
    write_setting_i(sesskey, "FontVTMode", cfg->vtmode);
    write_setting_i(sesskey, "UseSystemColours", cfg->system_colour);
    write_setting_i(sesskey, "TryPalette", cfg->try_palette);
    write_setting_i(sesskey, "ANSIColour", cfg->ansi_colour);
    write_setting_i(sesskey, "Xterm256Colour", cfg->xterm_256_colour);
    write_setting_i(sesskey, "BoldAsColour", cfg->bold_colour);

    for (i = 0; i < 24; i++) {
	char buf[20], buf2[30];
	sprintf(buf, "Colour%d", i);
	sprintf(buf2, "%d,%d,%d", cfg->colours[i][0],
		cfg->colours[i][1], cfg->colours[i][2]);
	write_setting_s(sesskey, buf, buf2);
    }
    write_setting_i(sesskey, "RawCNP", cfg->rawcnp);
    write_setting_i(sesskey, "PasteRTF", cfg->rtf_paste);
    write_setting_s(sesskey, "IgnoreChars", cfg->ignore_chars);
    write_setting_i(sesskey, "MouseIsXterm", cfg->mouse_is_xterm);
    write_setting_i(sesskey, "RectSelect", cfg->rect_select);
    write_setting_i(sesskey, "MouseOverride", cfg->mouse_override);
    for (i = 0; i < 256; i += 32) {
	char buf[20], buf2[256];
	int j;
	sprintf(buf, "Wordness%d", i);
	*buf2 = '\0';
	for (j = i; j < i + 32; j++) {
	    sprintf(buf2 + strlen(buf2), "%s%d",
		    (*buf2 ? "," : ""), cfg->wordness[j]);
	}
	write_setting_s(sesskey, buf, buf2);
    }
    write_setting_s(sesskey, "LineCodePage", cfg->line_codepage);
    write_setting_i(sesskey, "CJKAmbigWide", cfg->cjk_ambig_wide);
    write_setting_i(sesskey, "UTF8Override", cfg->utf8_override);
    write_setting_s(sesskey, "Printer", cfg->printer);
    write_setting_i(sesskey, "CapsLockCyr", cfg->xlat_capslockcyr);
    write_setting_i(sesskey, "Use5Casis", cfg->use_5casis);
    write_setting_i(sesskey, "ScrollBar", cfg->scrollbar);
    write_setting_i(sesskey, "ScrollBarFullScreen", cfg->scrollbar_in_fullscreen);
    write_setting_i(sesskey, "ScrollOnKey", cfg->scroll_on_key);
    write_setting_i(sesskey, "ScrollOnDisp", cfg->scroll_on_disp);
    write_setting_i(sesskey, "EraseToScrollback", cfg->erase_to_scrollback);
    write_setting_i(sesskey, "LockSize", cfg->resize_action);
    write_setting_i(sesskey, "BCE", cfg->bce);
    write_setting_i(sesskey, "BlinkText", cfg->blinktext);
    write_setting_i(sesskey, "X11Forward", cfg->x11_forward);
    write_setting_s(sesskey, "X11Display", cfg->x11_display);
    write_setting_i(sesskey, "X11AuthType", cfg->x11_auth);
    write_setting_filename(sesskey, "X11AuthFile", cfg->xauthfile);
    write_setting_i(sesskey, "LocalPortAcceptAll", cfg->lport_acceptall);
    write_setting_i(sesskey, "RemotePortAcceptAll", cfg->rport_acceptall);
    wmap(sesskey, "PortForwardings", cfg->portfwd, lenof(cfg->portfwd));
    write_setting_i(sesskey, "BugIgnore1", 2-cfg->sshbug_ignore1);
    write_setting_i(sesskey, "BugPlainPW1", 2-cfg->sshbug_plainpw1);
    write_setting_i(sesskey, "BugRSA1", 2-cfg->sshbug_rsa1);
    write_setting_i(sesskey, "BugIgnore2", 2-cfg->sshbug_ignore2);
    write_setting_i(sesskey, "BugHMAC2", 2-cfg->sshbug_hmac2);
    write_setting_i(sesskey, "BugDeriveKey2", 2-cfg->sshbug_derivekey2);
    write_setting_i(sesskey, "BugRSAPad2", 2-cfg->sshbug_rsapad2);
    write_setting_i(sesskey, "BugPKSessID2", 2-cfg->sshbug_pksessid2);
    write_setting_i(sesskey, "BugRekey2", 2-cfg->sshbug_rekey2);
    write_setting_i(sesskey, "BugMaxPkt2", 2-cfg->sshbug_maxpkt2);
    write_setting_i(sesskey, "StampUtmp", cfg->stamp_utmp);
    write_setting_i(sesskey, "LoginShell", cfg->login_shell);
    write_setting_i(sesskey, "ScrollbarOnLeft", cfg->scrollbar_on_left);
    write_setting_fontspec(sesskey, "BoldFont", cfg->boldfont);
    write_setting_fontspec(sesskey, "WideFont", cfg->widefont);
    write_setting_fontspec(sesskey, "WideBoldFont", cfg->wideboldfont);
    write_setting_i(sesskey, "ShadowBold", cfg->shadowbold);
    write_setting_i(sesskey, "ShadowBoldOffset", cfg->shadowboldoffset);
    write_setting_s(sesskey, "SerialLine", cfg->serline);
    write_setting_i(sesskey, "SerialSpeed", cfg->serspeed);
    write_setting_i(sesskey, "SerialDataBits", cfg->serdatabits);
    write_setting_i(sesskey, "SerialStopHalfbits", cfg->serstopbits);
    write_setting_i(sesskey, "SerialParity", cfg->serparity);
    write_setting_i(sesskey, "SerialFlowControl", cfg->serflow);
    write_setting_s(sesskey, "WindowClass", cfg->winclass);

    /* HACK: PuttyTray / Reconnect */
    write_setting_i(sesskey, "WakeupReconnect", cfg->wakeup_reconnect);
    write_setting_i(sesskey, "FailureReconnect", cfg->failure_reconnect);

    /* Hyperlink */
    write_setting_i(sesskey, "HyperlinkEnable", cfg->url_enable);
    write_setting_i(sesskey, "HyperlinkUnderline", cfg->url_underline);
    write_setting_i(sesskey, "HyperlinkUseCtrlClick", cfg->url_ctrl_click);

    /* Background */
    write_setting_i(sesskey, "BackgroundWallpaper", cfg->bg_wallpaper);
    write_setting_i(sesskey, "BackgroundEffect", cfg->bg_effect);
    write_setting_filename(sesskey, "WallpaperFile", cfg->wp_file);
    write_setting_i(sesskey, "WallpaperPosition", cfg->wp_position);
    write_setting_i(sesskey, "WallpaperAlign", cfg->wp_align);
    write_setting_i(sesskey, "WallpaperVerticalAlign", cfg->wp_valign);
    write_setting_i(sesskey, "WallpaperMoving", cfg->wp_moving);

    /* Transparency */
    for (i = 0; i < 4; i++) {
	char buf[16], buf2[16];
	sprintf(buf, "Alpha%d", i);
	sprintf(buf2, "%d,%d", cfg->alphas_pc[i][0], cfg->alphas_pc[i][1]);
	write_setting_s(sesskey, buf, buf2);
    }
}
예제 #23
0
int read_config(int reload)
{
    FILE *config;
    int linenum = 0, retval = 1;
    char buf[1024], *s;
    int defconCount = 0;

    if (reload) {
        int i, n;

        /* Reset all the reloadable settings */

        for (n = 0; n < lenof(directives); n++) {
            Directive *d = &directives[n];

            for (i = 0; i < MAXPARAMS && d->params[i].type != PARAM_NONE;
                 i++) {
                if (!(d->params[i].flags & PARAM_RELOAD))
                    continue;

                if (d->params[i].type == PARAM_SET
                    || d->params[i].type == PARAM_INT
                    || d->params[i].type == PARAM_POSINT
                    || d->params[i].type == PARAM_TIME) {
                    *(int *) d->params[i].ptr = 0;
                } else if (d->params[i].type == PARAM_STRING) {
                    if (*(char **) d->params[i].ptr)
                        free(*(char **) d->params[i].ptr);
                    (*(char **) d->params[i].ptr) = NULL;
                }
            }
        }
    }

    config = fopen(SERVICES_CONF, "r");
    if (!config) {
#ifndef NOT_MAIN
        log_perror("Can't open " SERVICES_CONF);
        if (!nofork && isatty(2)) {
#endif
            if (!reload)
                perror("Can't open " SERVICES_CONF);
            else
                alog("Can't open %s", SERVICES_CONF);
#ifndef NOT_MAIN
        }
#endif
        return 0;
    }
    while (fgets(buf, sizeof(buf), config)) {
        linenum++;
        if (*buf == '#' || *buf == '\r' || *buf == '\n')
            continue;
        if (!parse(buf, linenum, reload))
            retval = 0;
    }
    fclose(config);

    if (!reload) {
        CHECK(RemoteServer);
        CHECK(ServerName);
        CHECK(ServerDesc);

        if (RemoteServer3)
            CHECK(RemoteServer2);

        if (LocalHost && RemoteServer) {
            if ((!stricmp(LocalHost, RemoteServer))
                && LocalPort == RemotePort) {
                printf
                    ("\n*** LocalAddress and RemoteServer are set to use the same IP address\n"
                     "*** (%s) and port (%d). This would have resulted in errors.\n"
                     "*** Change the LocalAddress to bind to another port.\n",
                     RemoteServer, LocalPort);
                retval = 0;
            }
        }

        if (NickLen == 0) {
            alog("You have not defined the NickLen configuration directive. It is strongly");
            alog("advised that you do configure this correctly in your services.conf");
            NickLen = NICKMAX - 1;
        } else if ((NickLen < 1) || (NickLen >= NICKMAX)) {
            alog("NickLen has an invalid value; setting to %d",
                 (NICKMAX - 1));
            NickLen = NICKMAX - 1;
        }
    }

    CHECK(IRCDModule);
    CHECK(EncModule);

    CHECK(NetworkName);
    if (!reload) {
        CHEK2(temp_userhost, ServiceUser);
        CHEK2(s_NickServ, NickServName);
        CHEK2(s_ChanServ, ChanServName);
        CHEK2(s_MemoServ, MemoServName);
        CHEK2(s_HelpServ, HelpServName);
        CHEK2(s_OperServ, OperServName);
        CHEK2(s_GlobalNoticer, GlobalName);
        CHEK2(PIDFilename, PIDFile);
    }

    if (s_ChanServAlias) {
        if (!stricmp(s_ChanServ, s_ChanServAlias)) {
            printf
                ("\n*** ChanServ and ChanServ Alias are the same, this will cause errors\n");
            retval = 0;
        }
    }

    if (s_NickServAlias) {
        if (!stricmp(s_NickServ, s_NickServAlias)) {
            printf
                ("\n*** NickServ and NickServ Alias are the same, this will cause errors\n");
            retval = 0;
        }
    }

    if (s_OperServAlias) {
        if (!stricmp(s_OperServ, s_OperServAlias)) {
            printf
                ("\n*** OperServ and OperServ Alias are the same, this will cause errors\n");
            retval = 0;
        }
    }

    if (s_MemoServAlias) {
        if (!stricmp(s_MemoServ, s_MemoServAlias)) {
            printf
                ("\n*** MemoServ and MemoServ Alias are the same, this will cause errors\n");
            retval = 0;
        }
    }

    if (s_HelpServAlias) {
        if (!stricmp(s_HelpServ, s_HelpServAlias)) {
            printf
                ("\n*** HelpServ and HelpServ Alias are the same, this will cause errors\n");
            retval = 0;
        }
    }

    if (s_GlobalNoticerAlias) {
        if (!stricmp(s_GlobalNoticer, s_GlobalNoticerAlias)) {
            printf
                ("\n*** GlobalNoticer and GlobalNoticer Alias are the same, this will cause errors\n");
            retval = 0;
        }
    }


    CHEK2(MOTDFilename, MOTDFile);
    if (!reload) {
        CHEK2(NickDBName, NickServDB);
        CHEK2(ChanDBName, ChanServDB);
        CHEK2(OperDBName, OperServDB);
        CHEK2(NewsDBName, NewsDB);
        CHEK2(ExceptionDBName, ExceptionDB);
    }
    CHECK(UpdateTimeout);
    CHECK(ExpireTimeout);
    CHECK(ReadTimeout);
    CHECK(WarningTimeout);
    CHECK(TimeoutCheck);
    CHECK(NSAccessMax);
    CHEK2(temp_nsuserhost, NSEnforcerUser);
    CHECK(NSReleaseTimeout);
    CHECK(NSListMax);
    CHECK(CSAccessMax);
    CHECK(CSAutokickMax);
    CHECK(CSAutokickReason);
    CHECK(CSInhabit);
    CHECK(CSListMax);
    CHECK(ServicesRoot);
    CHECK(AutokillExpiry);
    CHECK(ChankillExpiry);
    CHECK(SGLineExpiry);
    CHECK(SQLineExpiry);
    CHECK(SZLineExpiry);

    if (!reload) {

        if (temp_userhost) {
            if (!(s = strchr(temp_userhost, '@'))) {
                error(0, "Missing `@' for ServiceUser");
            } else {
                *s++ = 0;
                ServiceUser = temp_userhost;
                ServiceHost = s;
            }
        }

    }

    if (temp_nsuserhost) {
        if (!(s = strchr(temp_nsuserhost, '@'))) {
            NSEnforcerUser = temp_nsuserhost;
            NSEnforcerHost = ServiceHost;
        } else {
            *s++ = 0;
            NSEnforcerUser = temp_nsuserhost;
            NSEnforcerHost = s;
        }
    }

    if (!NSDefNone &&
        !NSDefKill &&
        !NSDefKillQuick &&
        !NSDefSecure &&
        !NSDefPrivate &&
        !NSDefHideEmail &&
        !NSDefHideUsermask &&
        !NSDefHideQuit && !NSDefMemoSignon && !NSDefMemoReceive) {
        NSDefSecure = 1;
        NSDefMemoSignon = 1;
        NSDefMemoReceive = 1;
    }

    NSDefFlags = 0;
    if (!NSDefNone) {
        if (NSDefKill)
            NSDefFlags |= NI_KILLPROTECT;
        if (NSDefKillQuick)
            NSDefFlags |= NI_KILL_QUICK;
        if (NSDefSecure)
            NSDefFlags |= NI_SECURE;
        if (NSDefPrivate)
            NSDefFlags |= NI_PRIVATE;
        if (NSDefMsg) {
            if (!UsePrivmsg)
                alog("NSDefMsg can only be used when UsePrivmsg is set - unsetting NSDefMsg");
            else
                NSDefFlags |= NI_MSG;
        }
        if (NSDefHideEmail)
            NSDefFlags |= NI_HIDE_EMAIL;
        if (NSDefHideUsermask)
            NSDefFlags |= NI_HIDE_MASK;
        if (NSDefHideQuit)
            NSDefFlags |= NI_HIDE_QUIT;
        if (NSDefMemoSignon)
            NSDefFlags |= NI_MEMO_SIGNON;
        if (NSDefMemoReceive)
            NSDefFlags |= NI_MEMO_RECEIVE;
        if (!NSDefAutoop)
            NSDefFlags |= NI_AUTOOP;
    }

    if (!ServicesRoot) {
        error(0,
              "You must define the 'ServicesRoot' configuration directive");
        error(0,
              "in your services.conf file. This is a required setting that");
        error(0,
              "defines the main Administrative nick(s) Anope will obey.");
        retval = 0;
    }

    CHECK(NSGuestNickPrefix);   /* Add safety check */
    if (NSGuestNickPrefix && (strlen(NSGuestNickPrefix) > 21)) {
        error(0, "Value of NSGuestNickPrefix must be between 1 and 21");
        retval = 0;
    }

    CHECK(NSDefLanguage);
    if (NSDefLanguage) {
        NSDefLanguage--;
        if (NSDefLanguage < 0 || NSDefLanguage >= NUM_LANGS) {
            error(0, "Value of NSDefLanguage must be between 1 and %d",
                  USED_LANGS);
            retval = 0;
        }
    }

    if (!NewsCount) {
        NewsCount = 3;
    }

    if (reload) {
        if ((NSDefLanguage = langlist[NSDefLanguage]) < 0)
            NSDefLanguage = DEF_LANGUAGE;
    }

    if (CSDefBantype < 0 || CSDefBantype > 3) {
        error(0, "Value of CSDefBantype must be between 0 and 3 included");
        retval = 0;
    }

    if (!MysqlRetries || !MysqlRetryGap) {
        MysqlRetries = 5;
        MysqlRetryGap = 1;
    } else if (((MysqlRetries * MysqlRetryGap) > 60)
               || ((MysqlRetries * MysqlRetryGap) < 1)) {
        error(0,
              "MysqlRetries * MysqlRetryGap must be between 1 and 60, using standard values.");
        MysqlRetries = 5;
        MysqlRetryGap = 1;
    }

    if (!CSDefNone &&
        !CSDefKeepTopic &&
        !CSDefTopicLock &&
        !CSDefPrivate &&
        !CSDefRestricted &&
        !CSDefSecure &&
        !CSDefSecureOps &&
        !CSDefSecureFounder &&
        !CSDefSignKick && !CSDefSignKickLevel && !CSDefOpNotice) {
        CSDefKeepTopic = 1;
        CSDefSecure = 1;
        CSDefSecureFounder = 1;
        CSDefSignKick = 1;
    }

    CSDefFlags = 0;
    if (!CSDefNone) {
        if (CSDefKeepTopic)
            CSDefFlags |= CI_KEEPTOPIC;
        if (CSDefTopicLock)
            CSDefFlags |= CI_TOPICLOCK;
        if (CSDefPrivate)
            CSDefFlags |= CI_PRIVATE;
        if (CSDefRestricted)
            CSDefFlags |= CI_RESTRICTED;
        if (CSDefSecure)
            CSDefFlags |= CI_SECURE;
        if (CSDefSecureOps)
            CSDefFlags |= CI_SECUREOPS;
        if (CSDefSecureFounder)
            CSDefFlags |= CI_SECUREFOUNDER;
        if (CSDefSignKick)
            CSDefFlags |= CI_SIGNKICK;
        if (CSDefSignKickLevel)
            CSDefFlags |= CI_SIGNKICK_LEVEL;
        if (CSDefOpNotice)
            CSDefFlags |= CI_OPNOTICE;
        if (CSDefXOP)
            CSDefFlags |= CI_XOP;
        if (CSDefPeace)
            CSDefFlags |= CI_PEACE;
    }

    BSDefFlags = 0;
    if (BSDefDontKickOps)
        BSDefFlags |= BS_DONTKICKOPS;
    if (BSDefDontKickVoices)
        BSDefFlags |= BS_DONTKICKVOICES;
    if (BSDefGreet)
        BSDefFlags |= BS_GREET;
    if (BSDefFantasy)
        BSDefFlags |= BS_FANTASY;
    if (BSDefSymbiosis)
        BSDefFlags |= BS_SYMBIOSIS;

    /* Services Root building */

    if (ServicesRoot && !reload) {      /* Check to prevent segmentation fault if it's missing */
        while( RootNumber )
            free(ServicesRoots[--RootNumber]);

        s = strtok(ServicesRoot, " ");
        do {
            if (s) {
                RootNumber++;
                ServicesRoots =
                    srealloc(ServicesRoots, sizeof(char *) * RootNumber);
                ServicesRoots[RootNumber - 1] = sstrdup(s);
            }
        } while ((s = strtok(NULL, " ")));
    }

    if (!RootNumber) {
        error(0, "No ServicesRoot defined");
        retval = 0;
    }

    /* Ulines */

    if (UlineServers) {
        while( NumUlines )
            free(Ulines[--NumUlines]);

        s = strtok(UlineServers, " ");
        do {
            if (s) {
                NumUlines++;
                Ulines = srealloc(Ulines, sizeof(char *) * NumUlines);
                Ulines[NumUlines - 1] = sstrdup(s);
            }
        } while ((s = strtok(NULL, " ")));
    }

    /* Host Setters building... :P */
    while( HostNumber )
        free(HostSetters[--HostNumber]);
    Anope_Free(HostSetters);
    HostSetters = buildStringList(HostSetter, &HostNumber);

    /* Modules Autoload building... :P */
    while( ModulesNumber )
        free(ModulesAutoload[--ModulesNumber]);
    Anope_Free(ModulesAutoload);
    ModulesAutoload = buildStringList(Modules, &ModulesNumber);

    while( ModulesDelayedNumber )
        free(ModulesDelayedAutoload[--ModulesDelayedNumber]);
    Anope_Free(ModulesDelayedAutoload);
    ModulesDelayedAutoload = buildStringList(ModulesDelayed, &ModulesDelayedNumber);

    while( HostServCoreNumber )
        free(HostServCoreModules[--HostServCoreNumber]);
    Anope_Free(HostServCoreModules);
    HostServCoreModules = buildStringList(HostCoreModules, &HostServCoreNumber);

    while( MemoServCoreNumber )
        free(MemoServCoreModules[--MemoServCoreNumber]);
    Anope_Free(MemoServCoreModules);
    MemoServCoreModules = buildStringList(MemoCoreModules, &MemoServCoreNumber);

    while( HelpServCoreNumber )
        free(HelpServCoreModules[--HelpServCoreNumber]);
    Anope_Free(HelpServCoreModules);
    HelpServCoreModules = buildStringList(HelpCoreModules, &HelpServCoreNumber);

    while( BotServCoreNumber )
        free(BotServCoreModules[--BotServCoreNumber]);
    Anope_Free(BotServCoreModules);
    BotServCoreModules = buildStringList(BotCoreModules, &BotServCoreNumber);

    while( OperServCoreNumber )
        free(OperServCoreModules[--OperServCoreNumber]);
    Anope_Free(OperServCoreModules);
    OperServCoreModules = buildStringList(OperCoreModules, &OperServCoreNumber);

    while( ChanServCoreNumber )
        free(ChanServCoreModules[--ChanServCoreNumber]);
    Anope_Free(ChanServCoreModules);
    ChanServCoreModules = buildStringList(ChanCoreModules, &ChanServCoreNumber);

    while( NickServCoreNumber )
        free(NickServCoreModules[--NickServCoreNumber]);
    Anope_Free(NickServCoreModules);
    NickServCoreModules = buildStringList(NickCoreModules, &NickServCoreNumber);


    if (LimitSessions) {
        CHECK(DefSessionLimit);
        CHECK(MaxSessionLimit);
        CHECK(ExceptionExpiry);

        if (MaxSessionKill && !SessionAutoKillExpiry)
            SessionAutoKillExpiry = 30 * 60;    /* 30 minutes */
    }

    if (s_BotServ) {
        CHEK2(BotDBName, BotServDB);
        CHECK(BSBadWordsMax);
        CHECK(BSMinUsers);
        CHECK(BSKeepData);
        if (s_BotServAlias) {
            if (!stricmp(s_BotServ, s_BotServAlias)) {
                printf
                    ("\n*** BotServ and BotServ Alias are the same, this will cause errors\n");
                retval = 0;
            }
        }
        if (!BSFantasyCharacter)
            BSFantasyCharacter = sstrdup("!");
        if (BSFantasyCharacter && (strlen(BSFantasyCharacter) > 1)) {
            printf
                ("*** BSFantasyCharacter is more than 1 character long. Only the first\n"
                 "*** character ('%c') will be used. The others will be ignored.\n",
                 *BSFantasyCharacter);
        }
    }

    if (s_HostServ) {
        CHEK2(s_HostServ, HostServName);
        CHEK2(HostDBName, HostServDB);

        if (s_HostServAlias) {
            if (!stricmp(s_HostServ, s_HostServAlias)) {
                printf
                    ("\n*** HostServ and HostServ Alias are the same, this will cause errors\n");
                retval = 0;
            }
        }
    }

    if (UseMail) {
        CHECK(SendMailPath);
        CHECK(SendFrom);
    }

    if (GlobalOnCycle) {
        if (!GlobalOnCycleMessage && !GlobalOnCycleUP) {
            alog("GlobalOnCycleMessage and GlobalOnCycleUP are not defined; disabling GlobalOnCycle");
            GlobalOnCycle = 0;
        }
    }

    /* Check the user keys */
    if ((UserKey1 == UserKey2) || (UserKey1 == UserKey3)
        || (UserKey3 == UserKey2))
        alog("Every UserKey must be different. It's for YOUR safety! Remember that!");

    /**
     * Check all DEFCON dependiencies...
     **/
    if (DefConLevel) {
        CHECK(DefCon1);
        CHECK(DefCon2);
        CHECK(DefCon3);
        CHECK(DefCon4);
        DefCon5 = 0;            /* ALWAYS have defcon 5 as normal operation */
        /* Build DefCon's */
        DefCon[0] = 0;
        DefCon[1] = DefCon1;
        DefCon[2] = DefCon2;
        DefCon[3] = DefCon3;
        DefCon[4] = DefCon4;
        DefCon[5] = DefCon5;
        for (defconCount = 1; defconCount <= 5; defconCount++) {        /* Check any defcon needed settings */
            if (DefCon[defconCount] & DEFCON_REDUCE_SESSION) {
                CHECK(DefConSessionLimit);
            }
            if (DefCon[defconCount] & DEFCON_AKILL_NEW_CLIENTS) {
                CHECK(DefConAKILL);
                CHECK(DefConAkillReason);
            }
            if (DefCon[defconCount] & DEFCON_FORCE_CHAN_MODES) {
                CHECK(DefConChanModes);
            }
        }
        if (GlobalOnDefconMore)
            CHECK(DefconMessage);
    }

    /**
     * If they try to enable any email registration option,
     * make sure they have everything else they need too...
     *
     * rob
     **/
    if (NSEmailReg) {
        CHEK2(PreNickDBName, PreNickServDB);
        CHECK(NSEmailReg);
        CHECK(NSRExpire);
        CHECK(UseMail);
        CHECK(NSForceEmail);
    } else {
        Anope_Free(PreNickDBName);
        PreNickDBName = NULL;
        NSRExpire = 0;
    }

    if (!retval) {
        printf
            ("\n*** Support resources: Read through the services.conf self-contained \n*** documentation. Read the documentation files found in the 'docs' \n*** folder. Visit our portal located at http://www.anope.org/. Join \n*** our support channel on /server irc.anope.org channel #anope.\n\n");
    }

    return retval;
}
예제 #24
0
파일: SSHDH.C 프로젝트: AlexKir/Far-NetBox
    0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, 0x9B, 0x27, 0x83, 0xA2,
    0xEC, 0x07, 0xA2, 0x8F, 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9,
    0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, 0x39, 0x95, 0x49, 0x7C,
    0xEA, 0x95, 0x6A, 0xE5, 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,
    0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAC, 0xAA, 0x68, 0xFF, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFF
};

/*
 * The generator g = 2 (used for both group1 and group14).
 */
static const unsigned char G[] = { 2 };

static const struct ssh_kex ssh_diffiehellman_group1_sha1 = {
    "diffie-hellman-group1-sha1", "group1",
    KEXTYPE_DH, P1, G, lenof(P1), lenof(G), &ssh_sha1
};

static const struct ssh_kex *const group1_list[] = {
    &ssh_diffiehellman_group1_sha1
};

const struct ssh_kexes ssh_diffiehellman_group1 = {
    sizeof(group1_list) / sizeof(*group1_list),
    group1_list
};

static const struct ssh_kex ssh_diffiehellman_group14_sha1 = {
    "diffie-hellman-group14-sha1", "group14",
    KEXTYPE_DH, P14, G, lenof(P14), lenof(G), &ssh_sha1
};
예제 #25
0
	//*************************************************************************
	// Method:		fillModuleListTH32
	// Description: support function
	//
	//*************************************************************************
	bool StackWalker::fillModuleListTH32( ModuleList& modules, DWORD pid )
	{
		// CreateToolhelp32Snapshot()
		typedef HANDLE (__stdcall *tCT32S)( DWORD dwFlags, DWORD th32ProcessID );
		// Module32First()
		typedef BOOL (__stdcall *tM32F)( HANDLE hSnapshot, LPMODULEENTRY32 lpme );
		// Module32Next()
		typedef BOOL (__stdcall *tM32N)( HANDLE hSnapshot, LPMODULEENTRY32 lpme );

		// I think the DLL is called tlhelp32.dll on Win9X, so we try both
		const char *dllname[] = { "kernel32.dll", "tlhelp32.dll" };
		HINSTANCE hToolhelp;
		tCT32S pCT32S;
		tM32F pM32F;
		tM32N pM32N;

		HANDLE hSnap;
		MODULEENTRY32 me = { sizeof me };
		bool keepGoing;
		ModuleEntry e;
		int i;

		for ( i = 0; i < lenof( dllname ); ++ i )
		{
			hToolhelp = LoadLibrary( dllname[i] );
			if ( hToolhelp == 0 )
				continue;
			pCT32S = (tCT32S) GetProcAddress( hToolhelp, "CreateToolhelp32Snapshot" );
			pM32F = (tM32F) GetProcAddress( hToolhelp, "Module32First" );
			pM32N = (tM32N) GetProcAddress( hToolhelp, "Module32Next" );
			if ( pCT32S != 0 && pM32F != 0 && pM32N != 0 )
				break; // found the functions!
			FreeLibrary( hToolhelp );
			hToolhelp = 0;
		}

		if ( hToolhelp == 0 ) // nothing found?
			return false;

		hSnap = pCT32S( TH32CS_SNAPMODULE, pid );
		if ( hSnap == (HANDLE) -1 )
			return false;

		keepGoing = !!pM32F( hSnap, &me );
		while ( keepGoing )
		{
			// here, we have a filled-in MODULEENTRY32
			//printf( "%08lXh %6lu %-15.15s %s\n", me.modBaseAddr, me.modBaseSize, me.szModule, me.szExePath );
			e.imageName = me.szExePath;
			e.moduleName = me.szModule;
			e.baseAddress = (DWORD) me.modBaseAddr;
			e.size = me.modBaseSize;
			modules.push_back( e );
			keepGoing = !!pM32N( hSnap, &me );
		}

		CloseHandle( hSnap );

		FreeLibrary( hToolhelp );

		return modules.size() != 0;
	}
예제 #26
0
void DEBUGSTR( int level, LPTSTR szFormat, ... )
{
  static char  tempfile[MAX_PATH];
  static DWORD pid;

  TCHAR   szBuffer[1024], szEscape[1024];
  va_list pArgList;
  HANDLE  mutex;
  DWORD   wait;
  FILE*   file;

  if ((log_level & 3) < level && !(level & 4 & log_level))
    return;

  if (*tempfile == '\0')
  {
    _snprintf( tempfile, MAX_PATH, "%s\\ansicon.log", getenv( "TEMP" ) );
    pid = GetCurrentProcessId();
  }
  if (szFormat == NULL)
  {
    // Explicitly use 't', as _fmode might be binary.
    file = fopen( tempfile, (log_level & 8) ? "at" : "wt" );
    if (file != NULL)
    {
      SYSTEMTIME now;
      GetLocalTime( &now );
      fseek( file, 0, SEEK_END );
      if (ftell( file ) != 0)
	putc( '\n', file );
      fprintf( file, "ANSICON (" BITSA "-bit) v" PVERSA " log (%d) started "
		      "%d-%.2d-%.2d %d:%.2d:%.2d\n",
		     log_level,
		     now.wYear, now.wMonth, now.wDay,
		     now.wHour, now.wMinute, now.wSecond );
      fclose( file );
    }
    return;
  }

  va_start( pArgList, szFormat );
  _vsnwprintf( szBuffer, lenof(szBuffer), szFormat, pArgList );
  va_end( pArgList );

  szFormat = szBuffer;
  if (*szFormat == '\33')
  {
    BOOL first = TRUE;
    LPTSTR pos = szEscape;
    while (*++szFormat != '\0' && pos < szEscape + lenof(szEscape) - 4)
    {
      if (*szFormat < 32)
      {
	*pos++ = '\\';
	switch (*szFormat)
	{
	  case '\a': *pos++ = 'a'; break;
	  case '\b': *pos++ = 'b'; break;
	  case '\t': *pos++ = 't'; break;
	  case '\r': *pos++ = 'r'; break;
	  case '\n': *pos++ = 'n'; break;
	  case	27 : *pos++ = 'e'; break;
	  default:
	    pos += _snwprintf( pos, 32, L"%.*o",
			     (szFormat[1] >= '0' && szFormat[1] <= '7') ? 3 : 1,
			     *szFormat );
	}
      }
      else
      {
	if (*szFormat == '"')
	{
	  if (first)
	    first = FALSE;
	  else if (szFormat[1] != '\0')
	    *pos++ = '\\';
	}
	*pos++ = *szFormat;
      }
    }
    *pos = '\0';
    szFormat = szEscape;
  }

  mutex = CreateMutex( NULL, FALSE, L"ANSICON_debug_file" );
  wait	= WaitForSingleObject( mutex, 500 );
  file	= fopen( tempfile, "at" );
  if (file != NULL)
  {
    fwprintf( file, L"%s (%lu): %s\n", prog, pid, szFormat );
    fclose( file );
  }
  if (wait == WAIT_OBJECT_0)
    ReleaseMutex( mutex );
  CloseHandle( mutex );
}
예제 #27
0
파일: ansicon.c 프로젝트: kmkkmk/app
//int _tmain( int argc, TCHAR* argv[] )
int main( void )
{
  STARTUPINFO si;
  PROCESS_INFORMATION pi;
  TCHAR*  cmd;
  BOOL	  option;
  BOOL	  opt_m;
  BOOL	  installed;
  HMODULE ansi;
  int	  rc = 0;

  int argc;
  LPWSTR* argv = CommandLineToArgvW( GetCommandLine(), &argc );

  if (argc > 1)
  {
    if (lstrcmp( argv[1], L"--help" ) == 0 ||
	(argv[1][0] == '-' && (argv[1][1] == '?' || argv[1][1] == 'h')) ||
	(argv[1][0] == '/' && argv[1][1] == '?'))
    {
      help();
      return rc;
    }
    if (lstrcmp( argv[1], L"--version" ) == 0)
    {
      _putws( L"ANSICON (" BITS L"-bit) version " PVERS L" (" PDATE L")." );
      return rc;
    }
  }

#if (MYDEBUG > 1)
  DEBUGSTR( NULL ); // create a new file
#endif

  option = (argc > 1 && argv[1][0] == '-');
  if (option && (towlower( argv[1][1] ) == 'i' ||
		 towlower( argv[1][1] ) == 'u'))
  {
    process_autorun( argv[1][1] );
    argv[1][1] = 'p';
  }

  get_original_attr();

  opt_m = FALSE;
  if (option && argv[1][1] == 'm')
  {
    WORD attr = 7;
    if (iswxdigit( argv[1][2] ))
    {
      attr = iswdigit( argv[1][2] ) ? argv[1][2] - '0'
				    : (argv[1][2] | 0x20) - 'a' + 10;
      if (iswxdigit( argv[1][3]))
      {
	attr <<= 4;
	attr |= iswdigit( argv[1][3] ) ? argv[1][3] - '0'
				       : (argv[1][3] | 0x20) - 'a' + 10;
      }
    }
    SetConsoleTextAttribute( hConOut, attr );

    opt_m = TRUE;
    ++argv;
    --argc;
    option = (argc > 1 && argv[1][0] == '-');
  }

  installed = (GetEnvironmentVariable( L"ANSICON", NULL, 0 ) != 0);

  if (option && argv[1][1] == 'p')
  {
    // If it's already installed, there's no need to do anything.
    if (installed)
      ;
    else if (GetParentProcessInfo( &pi ))
    {
      pi.hProcess = OpenProcess( PROCESS_ALL_ACCESS, FALSE, pi.dwProcessId );
      pi.hThread  = OpenThread(  THREAD_ALL_ACCESS,  FALSE, pi.dwThreadId  );
      SuspendThread( pi.hThread );
      if (!Inject( &pi ))
      {
	_putws( L"ANSICON: parent process type is not supported." );
	rc = 1;
      }
      ResumeThread( pi.hThread );
      CloseHandle( pi.hThread );
      CloseHandle( pi.hProcess );
    }
    else
    {
      _putws( L"ANSICON: could not obtain the parent process." );
      rc = 1;
    }
  }
  else
  {
    ansi = 0;
    if (!installed)
    {
      ansi = LoadLibrary( L"ANSI" BITS L".dll" );
      if (!ansi)
      {
	fputws( L"ANSICON: failed to load ANSI" BITS L".dll.\n", stderr );
	rc = 1;
      }
    }

    if (option && (argv[1][1] == 't' || argv[1][1] == 'T'))
    {
      BOOL title = (argv[1][1] == 'T');
      if (argc == 2)
      {
	argv[2] = L"-";
	++argc;
      }
      for (; argc > 2; ++argv, --argc)
      {
	if (title)
	  wprintf( L"==> %s <==\n", argv[2] );
	display( argv[2], title );
	if (title)
	  putwchar( '\n' );
      }
    }
    else
    {
      // Retrieve the original command line, skipping our name and the option.
      cmd = skip_spaces( skip_arg( skip_spaces( GetCommandLine() ) ) );
      if (opt_m)
	cmd = skip_spaces( skip_arg( cmd ) );

      if (cmd[0] == '-' && (cmd[1] == 'e' || cmd[1] == 'E'))
      {
	fputws( cmd + 3, stdout );
	if (cmd[1] == 'e')
	  putwchar( '\n' );
      }
      else if (!_isatty( 0 ) && *cmd == '\0')
      {
	display( L"-", FALSE );
      }
      else
      {
	if (*cmd == '\0')
	{
	  cmd = _wgetenv( L"ComSpec" );
	  if (cmd == NULL)
	    cmd = L"cmd";
	}

	ZeroMemory( &si, sizeof(si) );
	si.cb = sizeof(si);
	if (CreateProcess( NULL, cmd, NULL,NULL, TRUE, 0, NULL,NULL, &si, &pi ))
	{
	  BOOL	console = FALSE;
	  TCHAR name[MAX_PATH];
	  DWORD rc;
	  CoInitialize( NULL );
	  do
	  {
	    // When I first tried doing this, it took a little while to
	    // succeed.  Testing again shows it works immediately - perhaps the
	    // CoInitialize introduces enough of a delay.  Still, play it safe
	    // and keep trying.  And if you're wondering why I do it at all,
	    // ProcessType may detect GUI, even for a console process.	That's
	    // fine after injection (including -p), but not here.  We *need* to
	    // suspend our own execution whilst running the child, otherwise
	    // bad things happen (besides which, I want to restore the original
	    // attributes when the child exits).
	    if (GetModuleFileNameEx( pi.hProcess, NULL, name, lenof(name) ))
	    {
	      DWORD_PTR info;
	      info = SHGetFileInfo( name, 0, NULL, 0, SHGFI_EXETYPE );
	      if (info == 0x00004550) // console PE
		console = TRUE;
	      DEBUGSTR( L"%s", name );
	      DEBUGSTR( L"  %s (%p)", (console) ? L"Console" : L"Not console",
				      info );
	      break;
	    }
	    Sleep( 10 );
	  } while (GetExitCodeProcess( pi.hProcess, &rc ) &&
		   rc == STILL_ACTIVE);
	  CoUninitialize();
	  if (console)
	  {
	    SetConsoleCtrlHandler( (PHANDLER_ROUTINE)CtrlHandler, TRUE );
	    WaitForSingleObject( pi.hProcess, INFINITE );
	  }
	  CloseHandle( pi.hProcess );
	  CloseHandle( pi.hThread );
	}
	else
	{
	  *skip_arg( cmd ) = '\0';
	  wprintf( L"ANSICON: '%s' could not be executed.\n", cmd );
	  rc = 1;
	}
      }
    }

    if (ansi)
      FreeLibrary( ansi );
  }

  set_original_attr();
  return rc;
}
예제 #28
0
int main(int argc, char **argv)
{
    int i, j;

    if (argc > 1) {
	/*
	 * Generation of tests.
	 * 
	 * Given `-splat <args>', we print out a C-style
	 * representation of each argument (in the form "a", "b",
	 * NULL), backslash-escaping each backslash and double
	 * quote.
	 * 
	 * Given `-split <string>', we first doctor `string' by
	 * turning forward slashes into backslashes, single quotes
	 * into double quotes and underscores into spaces; and then
	 * we feed the resulting string to ourself with `-splat'.
	 * 
	 * Given `-generate', we concoct a variety of fun test
	 * cases, encode them in quote-safe form (mapping \, " and
	 * space to /, ' and _ respectively) and feed each one to
	 * `-split'.
	 */
	if (!strcmp(argv[1], "-splat")) {
	    int i;
	    char *p;
	    for (i = 2; i < argc; i++) {
		putchar('"');
		for (p = argv[i]; *p; p++) {
		    if (*p == '\\' || *p == '"')
			putchar('\\');
		    putchar(*p);
		}
		printf("\", ");
	    }
	    printf("NULL");
	    return 0;
	}

	if (!strcmp(argv[1], "-split") && argc > 2) {
	    char *str = malloc(20 + strlen(argv[0]) + strlen(argv[2]));
	    char *p, *q;

	    q = str + sprintf(str, "%s -splat ", argv[0]);
	    printf("    {\"");
	    for (p = argv[2]; *p; p++, q++) {
		switch (*p) {
		  case '/':  printf("\\\\"); *q = '\\'; break;
		  case '\'': printf("\\\""); *q = '"';  break;
		  case '_':  printf(" ");    *q = ' ';  break;
		  default:   putchar(*p);    *q = *p;   break;
		}
	    }
	    *p = '\0';
	    printf("\", {");
	    fflush(stdout);

	    system(str);

	    printf("}},\n");

	    return 0;
	}

	if (!strcmp(argv[1], "-generate")) {
	    char *teststr, *p;
	    int i, initialquote, backslashes, quotes;

	    teststr = malloc(200 + strlen(argv[0]));

	    for (initialquote = 0; initialquote <= 1; initialquote++) {
		for (backslashes = 0; backslashes < 5; backslashes++) {
		    for (quotes = 0; quotes < 9; quotes++) {
			p = teststr + sprintf(teststr, "%s -split ", argv[0]);
			if (initialquote) *p++ = '\'';
			*p++ = 'a';
			for (i = 0; i < backslashes; i++) *p++ = '/';
			for (i = 0; i < quotes; i++) *p++ = '\'';
			*p++ = 'b';
			*p++ = '_';
			*p++ = 'c';
			*p++ = '\'';
			*p++ = '_';
			*p++ = 'd';
			*p = '\0';

			system(teststr);
		    }
		}
	    }
	    return 0;
	}

	fprintf(stderr, "unrecognised option: \"%s\"\n", argv[1]);
	return 1;
    }

    /*
     * If we get here, we were invoked with no arguments, so just
     * run the tests.
     */

    for (i = 0; i < lenof(argv_tests); i++) {
	int ac;
	char **av;

	split_into_argv(argv_tests[i].cmdline, &ac, &av);

	for (j = 0; j < ac && argv_tests[i].argv[j]; j++) {
	    if (strcmp(av[j], argv_tests[i].argv[j])) {
		printf("failed test %d (|%s|) arg %d: |%s| should be |%s|\n",
		       i, argv_tests[i].cmdline,
		       j, av[j], argv_tests[i].argv[j]);
	    }
#ifdef VERBOSE
	    else {
		printf("test %d (|%s|) arg %d: |%s| == |%s|\n",
		       i, argv_tests[i].cmdline,
		       j, av[j], argv_tests[i].argv[j]);
	    }
#endif
	}
	if (j < ac)
	    printf("failed test %d (|%s|): %d args returned, should be %d\n",
		   i, argv_tests[i].cmdline, ac, j);
	if (argv_tests[i].argv[j])
	    printf("failed test %d (|%s|): %d args returned, should be more\n",
		   i, argv_tests[i].cmdline, ac);
    }

    return 0;
}
예제 #29
0
파일: SSHRSA.C 프로젝트: marsupial/rikiglue
/*
 * This function is a wrapper on modpow(). It has the same effect
 * as modpow(), but employs RSA blinding to protect against timing
 * attacks.
 */
static Bignum rsa_privkey_op(Bignum input, struct RSAKey *key)
{
    Bignum random, random_encrypted, random_inverse;
    Bignum input_blinded, ret_blinded;
    Bignum ret;

    SHA512_State ss;
    unsigned char digest512[64];
    int digestused = lenof(digest512);
    int hashseq = 0;

    /*
     * Start by inventing a random number chosen uniformly from the
     * range 2..modulus-1. (We do this by preparing a random number
     * of the right length and retrying if it's greater than the
     * modulus, to prevent any potential Bleichenbacher-like
     * attacks making use of the uneven distribution within the
     * range that would arise from just reducing our number mod n.
     * There are timing implications to the potential retries, of
     * course, but all they tell you is the modulus, which you
     * already knew.)
     * 
     * To preserve determinism and avoid Pageant needing to share
     * the random number pool, we actually generate this `random'
     * number by hashing stuff with the private key.
     */
    while (1) {
	int bits, byte, bitsleft, v;
	random = copybn(key->modulus);
	/*
	 * Find the topmost set bit. (This function will return its
	 * index plus one.) Then we'll set all bits from that one
	 * downwards randomly.
	 */
	bits = bignum_bitcount(random);
	byte = 0;
	bitsleft = 0;
	while (bits--) {
	    if (bitsleft <= 0) {
		bitsleft = 8;
		/*
		 * Conceptually the following few lines are equivalent to
		 *    byte = random_byte();
		 */
		if (digestused >= lenof(digest512)) {
		    unsigned char seqbuf[4];
		    PUT_32BIT(seqbuf, hashseq);
		    pSHA512_Init(&ss);
		    SHA512_Bytes(&ss, "RSA deterministic blinding", 26);
		    SHA512_Bytes(&ss, seqbuf, sizeof(seqbuf));
		    sha512_mpint(&ss, key->private_exponent);
		    pSHA512_Final(&ss, digest512);
		    hashseq++;

		    /*
		     * Now hash that digest plus the signature
		     * input.
		     */
		    pSHA512_Init(&ss);
		    SHA512_Bytes(&ss, digest512, sizeof(digest512));
		    sha512_mpint(&ss, input);
		    pSHA512_Final(&ss, digest512);

		    digestused = 0;
		}
		byte = digest512[digestused++];
	    }
	    v = byte & 1;
	    byte >>= 1;
	    bitsleft--;
	    bignum_set_bit(random, bits, v);
	}

	/*
	 * Now check that this number is strictly greater than
	 * zero, and strictly less than modulus.
	 */
	if (bignum_cmp(random, Zero) <= 0 ||
	    bignum_cmp(random, key->modulus) >= 0) {
	    freebn(random);
	    continue;
	} else {
	    break;
	}
    }

    /*
     * RSA blinding relies on the fact that (xy)^d mod n is equal
     * to (x^d mod n) * (y^d mod n) mod n. We invent a random pair
     * y and y^d; then we multiply x by y, raise to the power d mod
     * n as usual, and divide by y^d to recover x^d. Thus an
     * attacker can't correlate the timing of the modpow with the
     * input, because they don't know anything about the number
     * that was input to the actual modpow.
     * 
     * The clever bit is that we don't have to do a huge modpow to
     * get y and y^d; we will use the number we just invented as
     * _y^d_, and use the _public_ exponent to compute (y^d)^e = y
     * from it, which is much faster to do.
     */
    random_encrypted = modpow(random, key->exponent, key->modulus);
    random_inverse = modinv(random, key->modulus);
    input_blinded = modmul(input, random_encrypted, key->modulus);
    ret_blinded = modpow(input_blinded, key->private_exponent, key->modulus);
    ret = modmul(ret_blinded, random_inverse, key->modulus);

    freebn(ret_blinded);
    freebn(input_blinded);
    freebn(random_inverse);
    freebn(random_encrypted);
    freebn(random);

    return ret;
}
예제 #30
0
int asn1_load_mscat(fmap_t *map, struct cl_engine *engine) {
    struct cli_asn1 c;
    unsigned int size;
    struct cli_matcher *db;
    int i;

    if(asn1_parse_mscat(map, 0, map->len, &engine->cmgr, 0, &c.next, &size, engine))
        return 1;

    if(asn1_expect_objtype(map, c.next, &size, &c, 0x30))
	return 1;
    if(asn1_expect_obj(map, &c.content, &c.size, 0x06, lenof(OID_szOID_CATALOG_LIST), OID_szOID_CATALOG_LIST))
	return 1;
    if(c.size) {
	cli_dbgmsg("asn1_load_mscat: found extra data in szOID_CATALOG_LIST content\n");
	return 1;
    }
    if(asn1_expect_objtype(map, c.next, &size, &c, 0x4)) /* List ID */
	return 1;
    if(asn1_expect_objtype(map, c.next, &size, &c, 0x17)) /* Effective date - WTF?! */
	return 1;
    if(asn1_expect_algo(map, &c.next, &size, lenof(OID_szOID_CATALOG_LIST_MEMBER), OID_szOID_CATALOG_LIST_MEMBER)) /* szOID_CATALOG_LIST_MEMBER */
	return 1;
    if(asn1_expect_objtype(map, c.next, &size, &c, 0x30)) /* hashes here */
	return 1;
    /* [0] is next but we don't care as it's really descriptives stuff */

    size = c.size;
    c.next = c.content;
    while(size) {
	struct cli_asn1 tag;
	if(asn1_expect_objtype(map, c.next, &size, &c, 0x30))
	    return 1;
	if(asn1_expect_objtype(map, c.content, &c.size, &tag, 0x04)) /* TAG NAME */
	    return 1;
	if(asn1_expect_objtype(map, tag.next, &c.size, &tag, 0x31)) /* set */
	    return 1;
	if(c.size) {
	    cli_dbgmsg("asn1_load_mscat: found extra data in tag\n");
	    return 1;
	}
	while(tag.size) {
	    struct cli_asn1 tagval1, tagval2, tagval3;
	    int hashtype;

	    if(asn1_expect_objtype(map, tag.content, &tag.size, &tagval1, 0x30))
		return 1;
	    tag.content = tagval1.next;

	    if(asn1_expect_objtype(map, tagval1.content, &tagval1.size, &tagval2, 0x06))
		return 1;
	    if(tagval2.size != lenof(OID_SPC_INDIRECT_DATA_OBJID))
		continue;

	    if(!fmap_need_ptr_once(map, tagval2.content, lenof(OID_SPC_INDIRECT_DATA_OBJID))) {
		cli_dbgmsg("asn1_load_mscat: cannot read SPC_INDIRECT_DATA\n");
		return 1;
	    }
	    if(memcmp(tagval2.content, OID_SPC_INDIRECT_DATA_OBJID, lenof(OID_SPC_INDIRECT_DATA_OBJID)))
		continue; /* stuff like CAT_NAMEVALUE_OBJID(1.3.6.1.4.1.311.12.2.1) and CAT_MEMBERINFO_OBJID(.2).. */

	    if(asn1_expect_objtype(map, tagval2.next, &tagval1.size, &tagval2, 0x31))
		return 1;
	    if(tagval1.size) {
		cli_dbgmsg("asn1_load_mscat: found extra data in tag value\n");
		return 1;
	    }

	    if(asn1_expect_objtype(map, tagval2.content, &tagval2.size, &tagval1, 0x30))
		return 1;
	    if(tagval2.size) {
		cli_dbgmsg("asn1_load_mscat: found extra data in SPC_INDIRECT_DATA_OBJID tag\n");
		return 1;
	    }

	    if(asn1_expect_objtype(map, tagval1.content, &tagval1.size, &tagval2, 0x30))
		return 1;

	    if(asn1_expect_objtype(map, tagval2.content, &tagval2.size, &tagval3, 0x06)) /* shall have an obj 1.3.6.1.4.1.311.2.1.15 or 1.3.6.1.4.1.311.2.1.25 inside */
		return 1;
	    if(tagval3.size != lenof(OID_SPC_PE_IMAGE_DATA_OBJID)) { /* lenof(OID_SPC_PE_IMAGE_DATA_OBJID) = lenof(OID_SPC_CAB_DATA_OBJID) = 10*/
		cli_dbgmsg("asn1_load_mscat: bad hash type size\n");
		return 1;
	    }
	    if(!fmap_need_ptr_once(map, tagval3.content, lenof(OID_SPC_PE_IMAGE_DATA_OBJID))) {
		cli_dbgmsg("asn1_load_mscat: cannot read hash type\n");
		return 1;
	    }
	    if(!memcmp(tagval3.content, OID_SPC_PE_IMAGE_DATA_OBJID, lenof(OID_SPC_PE_IMAGE_DATA_OBJID)))
		hashtype = 2;
	    else if(!memcmp(tagval3.content, OID_SPC_CAB_DATA_OBJID, lenof(OID_SPC_CAB_DATA_OBJID)))
		hashtype = 1;
	    else {
		cli_dbgmsg("asn1_load_mscat: unexpected hash type\n");
		return 1;
	    }

	    if(asn1_expect_objtype(map, tagval2.next, &tagval1.size, &tagval2, 0x30))
		return 1;
	    if(tagval1.size) {
		cli_dbgmsg("asn1_load_mscat: found extra data after hash\n");
		return 1;
	    }

	    if(asn1_expect_algo(map, &tagval2.content, &tagval2.size, lenof(OID_sha1), OID_sha1)) /* objid 1.3.14.3.2.26 - sha1 */
		return 1;

	    if(asn1_expect_objtype(map, tagval2.content, &tagval2.size, &tagval3, 0x04))
		return 1;
	    if(tagval2.size) {
		cli_dbgmsg("asn1_load_mscat: found extra data in hash\n");
		return 1;
	    }
	    if(tagval3.size != SHA1_HASH_SIZE) {
		cli_dbgmsg("asn1_load_mscat: bad hash size %u\n", tagval3.size);
		return 1;
	    }
	    if(!fmap_need_ptr_once(map, tagval3.content, SHA1_HASH_SIZE)) {
		cli_dbgmsg("asn1_load_mscat: cannot read hash\n");
		return 1;
	    }

	    if(cli_debug_flag) {
		char sha1[SHA1_HASH_SIZE*2+1];
		for(i=0;i<SHA1_HASH_SIZE;i++)
		    sprintf(&sha1[i*2], "%02x", ((uint8_t *)(tagval3.content))[i]);
		cli_dbgmsg("asn1_load_mscat: got hash %s (%s)\n", sha1, (hashtype == 2) ? "PE" : "CAB");
	    }
	    if(!engine->hm_fp) {
		if(!(engine->hm_fp = mpool_calloc(engine->mempool, 1, sizeof(*db)))) {
		    tag.size = 1;;
		    return 1;
		}
#ifdef USE_MPOOL
		engine->hm_fp->mempool = engine->mempool;
#endif
	    }
	    if(hm_addhash_bin(engine->hm_fp, tagval3.content, CLI_HASH_SHA1, hashtype, NULL)) {
		cli_warnmsg("asn1_load_mscat: failed to add hash\n");
		return 1;
	    }
	}
    }

    return 0;
}