Пример #1
0
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
/*
 * 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
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
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
/**
 * 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
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
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
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
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
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
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
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
    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
//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
/*
 * 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;
}