Diff

Differences From Artifact [6ae9e3664c]:

To Artifact [0e672eb2ba]:


1858
1859
1860
1861
1862
1863
1864

1865
1866
1867




1868
1869
1870
1871
1872
1873
1874
1875











1876
1877
1878
1879
1880





1881
1882
1883
1884
1885
1886










1887
1888
1889






1890
1891
1892
1893
1894
1895
1896
1858
1859
1860
1861
1862
1863
1864
1865



1866
1867
1868
1869








1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880





1881
1882
1883
1884
1885






1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897

1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910







+
-
-
-
+
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+


-
+
+
+
+
+
+







    } else {
	rsaencrypt(rsabuf, 32, &hostkey);
	rsaencrypt(rsabuf, hostkey.bytes, &servkey);
    }

    logevent("Encrypted session key");

    {
    switch (cfg.cipher) {
      case CIPHER_BLOWFISH:
	cipher_type = SSH_CIPHER_BLOWFISH;
	int cipher_chosen = 0, warn = 0;
	char *cipher_string = NULL;
	for (i = 0; !cipher_chosen && i < CIPHER_MAX; i++) {
	    int next_cipher = cfg.ssh_cipherlist[i];
	break;
      case CIPHER_DES:
	cipher_type = SSH_CIPHER_DES;
	break;
      case CIPHER_3DES:
	cipher_type = SSH_CIPHER_3DES;
	break;
      case CIPHER_AES:
	    if (next_cipher == CIPHER_WARN) {
		/* If/when we choose a cipher, warn about it */
		warn = 1;
	    } else if (next_cipher == CIPHER_AES) {
		/* XXX Probably don't need to mention this. */
		logevent("AES not supported in SSH1, skipping");
	    } else {
		switch (next_cipher) {
		  case CIPHER_3DES:     cipher_type = SSH_CIPHER_3DES;
					cipher_string = "3DES"; break;
		  case CIPHER_BLOWFISH: cipher_type = SSH_CIPHER_BLOWFISH;
	c_write_str("AES not supported in SSH1, falling back to 3DES\r\n");
	cipher_type = SSH_CIPHER_3DES;
	break;
    }
    if ((supported_ciphers_mask & (1 << cipher_type)) == 0) {
					cipher_string = "Blowfish"; break;
		  case CIPHER_DES:	cipher_type = SSH_CIPHER_DES;
					cipher_string = "single-DES"; break;
		}
		if (supported_ciphers_mask & (1 << cipher_type))
	c_write_str
	    ("Selected cipher not supported, falling back to 3DES\r\n");
	cipher_type = SSH_CIPHER_3DES;
	if ((supported_ciphers_mask & (1 << cipher_type)) == 0) {
	    bombout(("Server violates SSH 1 protocol by "
		     "not supporting 3DES encryption"));
		    cipher_chosen = 1;
	    }
	}
	if (!cipher_chosen) {
	    if ((supported_ciphers_mask & (1 << SSH_CIPHER_3DES)) == 0)
		bombout(("Server violates SSH 1 protocol by not "
			 "supporting 3DES encryption"));
	    else
		/* shouldn't happen */
		bombout(("No supported ciphers found"));
	    crReturn(0);
	}
    }

	/* Warn about chosen cipher if necessary. */
	if (warn)
	    askcipher(cipher_string, 0);
    }

    switch (cipher_type) {
      case SSH_CIPHER_3DES:
	logevent("Using 3DES encryption");
	break;
      case SSH_CIPHER_DES:
	logevent("Using single-DES encryption");
	break;
2988
2989
2990
2991
2992
2993
2994
2995

2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011

3012

3013
3014
3015
3016
3017
3018
3019
3020
3021

3022



3023
3024
3025
3026
3027









3028
3029
3030
3031
3032







3033
3034
3035













3036
3037
3038
3039
3040
3041
3042
3002
3003
3004
3005
3006
3007
3008

3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026

3027
3028
3029
3030
3031
3032
3033
3034
3035

3036
3037
3038
3039
3040





3041
3042
3043
3044
3045
3046
3047
3048
3049





3050
3051
3052
3053
3054
3055
3056



3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076







-
+
















+
-
+








-
+

+
+
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
+
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+







}

/*
 * Handle the SSH2 transport layer.
 */
static int do_ssh2_transport(unsigned char *in, int inlen, int ispkt)
{
    static int i, j, len, nbits, pbits;
    static int i, j, len, nbits, pbits, warn;
    static char *str;
    static Bignum p, g, e, f, K;
    static int kex_init_value, kex_reply_value;
    static const struct ssh_mac **maclist;
    static int nmacs;
    static const struct ssh2_cipher *cscipher_tobe = NULL;
    static const struct ssh2_cipher *sccipher_tobe = NULL;
    static const struct ssh_mac *csmac_tobe = NULL;
    static const struct ssh_mac *scmac_tobe = NULL;
    static const struct ssh_compress *cscomp_tobe = NULL;
    static const struct ssh_compress *sccomp_tobe = NULL;
    static char *hostkeydata, *sigdata, *keystr, *fingerprint;
    static int hostkeylen, siglen;
    static void *hkey;		       /* actual host key */
    static unsigned char exchange_hash[20];
    static unsigned char keyspace[40];
    static int n_preferred_ciphers;
    static const struct ssh2_ciphers *preferred_cipher;
    static const struct ssh2_ciphers *preferred_ciphers[CIPHER_MAX];
    static const struct ssh_compress *preferred_comp;
    static int first_kex;

    crBegin;
    random_init();
    first_kex = 1;

    /*
     * Set up the preferred cipher and compression.
     * Set up the preferred ciphers. (NULL => warn below here)
     */
    n_preferred_ciphers = 0;
    for (i = 0; i < CIPHER_MAX; i++) {
	switch (cfg.ssh_cipherlist[i]) {
    if (cfg.cipher == CIPHER_BLOWFISH) {
	preferred_cipher = &ssh2_blowfish;
    } else if (cfg.cipher == CIPHER_DES) {
	logevent("Single DES not supported in SSH2; using 3DES");
	preferred_cipher = &ssh2_3des;
	  case CIPHER_BLOWFISH:
	    preferred_ciphers[n_preferred_ciphers] = &ssh2_blowfish;
	    n_preferred_ciphers++;
	    break;
	  case CIPHER_DES:
	    /* Not supported in SSH2; silently drop */
	    break;
	  case CIPHER_3DES:
	    preferred_ciphers[n_preferred_ciphers] = &ssh2_3des;
    } else if (cfg.cipher == CIPHER_3DES) {
	preferred_cipher = &ssh2_3des;
    } else if (cfg.cipher == CIPHER_AES) {
	preferred_cipher = &ssh2_aes;
    } else {
	    n_preferred_ciphers++;
	    break;
	  case CIPHER_AES:
	    preferred_ciphers[n_preferred_ciphers] = &ssh2_aes;
	    n_preferred_ciphers++;
	    break;
	  case CIPHER_WARN:
	/* Shouldn't happen, but we do want to initialise to _something_. */
	preferred_cipher = &ssh2_3des;
    }
	    /* Flag for later. Don't bother if it's the last in
	     * the list. */
	    if (i < CIPHER_MAX - 1) {
		preferred_ciphers[n_preferred_ciphers] = NULL;
		n_preferred_ciphers++;
	    }
	    break;
	}
    }

    /*
     * Set up preferred compression.
     */
    if (cfg.compression)
	preferred_comp = &ssh_zlib;
    else
	preferred_comp = &ssh_comp_none;

    /*
     * Be prepared to work around the buggy MAC problem.
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074



3075
3076
3077

3078
3079
3080
3081
3082
3083
3084
3085



3086
3087
3088

3089
3090
3091
3092
3093
3094
3095
3099
3100
3101
3102
3103
3104
3105



3106
3107
3108
3109
3110

3111
3112
3113
3114
3115
3116



3117
3118
3119
3120
3121

3122
3123
3124
3125
3126
3127
3128
3129







-
-
-
+
+
+


-
+





-
-
-
+
+
+


-
+







    for (i = 0; i < lenof(hostkey_algs); i++) {
	ssh2_pkt_addstring_str(hostkey_algs[i]->name);
	if (i < lenof(hostkey_algs) - 1)
	    ssh2_pkt_addstring_str(",");
    }
    /* List client->server encryption algorithms. */
    ssh2_pkt_addstring_start();
    for (i = 0; i < lenof(ciphers) + 1; i++) {
	const struct ssh2_ciphers *c =
	    i == 0 ? preferred_cipher : ciphers[i - 1];
    for (i = 0; i < n_preferred_ciphers; i++) {
	const struct ssh2_ciphers *c = preferred_ciphers[i];
	if (!c) continue;	       /* warning flag */
	for (j = 0; j < c->nciphers; j++) {
	    ssh2_pkt_addstring_str(c->list[j]->name);
	    if (i < lenof(ciphers) || j < c->nciphers - 1)
	    if (i < n_preferred_ciphers || j < c->nciphers - 1)
		ssh2_pkt_addstring_str(",");
	}
    }
    /* List server->client encryption algorithms. */
    ssh2_pkt_addstring_start();
    for (i = 0; i < lenof(ciphers) + 1; i++) {
	const struct ssh2_ciphers *c =
	    i == 0 ? preferred_cipher : ciphers[i - 1];
    for (i = 0; i < n_preferred_ciphers; i++) {
	const struct ssh2_ciphers *c = preferred_ciphers[i];
	if (!c) continue; /* warning flag */
	for (j = 0; j < c->nciphers; j++) {
	    ssh2_pkt_addstring_str(c->list[j]->name);
	    if (i < lenof(ciphers) || j < c->nciphers - 1)
	    if (i < n_preferred_ciphers || j < c->nciphers - 1)
		ssh2_pkt_addstring_str(",");
	}
    }
    /* List client->server MAC algorithms. */
    ssh2_pkt_addstring_start();
    for (i = 0; i < nmacs; i++) {
	ssh2_pkt_addstring_str(maclist[i]->name);
3167
3168
3169
3170
3171
3172
3173

3174
3175


3176
3177
3178
3179
3180
3181
3182
3183













3184
3185


3186

3187
3188


3189
3190
3191
3192
3193
3194
3195
3196













3197

3198
3199
3200
3201
3202
3203
3204
3201
3202
3203
3204
3205
3206
3207
3208


3209
3210








3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224

3225
3226
3227
3228


3229
3230








3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252







+
-
-
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+

-
+
+

+
-
-
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+

+







    for (i = 0; i < lenof(hostkey_algs); i++) {
	if (in_commasep_string(hostkey_algs[i]->name, str, len)) {
	    hostkey = hostkey_algs[i];
	    break;
	}
    }
    ssh2_pkt_getstring(&str, &len);    /* client->server cipher */
    warn = 0;
    for (i = 0; i < lenof(ciphers) + 1; i++) {
	const struct ssh2_ciphers *c =
    for (i = 0; i < n_preferred_ciphers; i++) {
	const struct ssh2_ciphers *c = preferred_ciphers[i];
	    i == 0 ? preferred_cipher : ciphers[i - 1];
	for (j = 0; j < c->nciphers; j++) {
	    if (in_commasep_string(c->list[j]->name, str, len)) {
		cscipher_tobe = c->list[j];
		break;
	    }
	}
	if (cscipher_tobe)
	if (!c) {
	    warn = 1;
	} else {
	    for (j = 0; j < c->nciphers; j++) {
		if (in_commasep_string(c->list[j]->name, str, len)) {
		    cscipher_tobe = c->list[j];
		    break;
		}
	    }
	}
	if (cscipher_tobe) {
	    if (warn)
		askcipher(cscipher_tobe->name, 1);
	    break;
    }
	}
    }
    ssh2_pkt_getstring(&str, &len);    /* server->client cipher */
    warn = 0;
    for (i = 0; i < lenof(ciphers) + 1; i++) {
	const struct ssh2_ciphers *c =
    for (i = 0; i < n_preferred_ciphers; i++) {
	const struct ssh2_ciphers *c = preferred_ciphers[i];
	    i == 0 ? preferred_cipher : ciphers[i - 1];
	for (j = 0; j < c->nciphers; j++) {
	    if (in_commasep_string(c->list[j]->name, str, len)) {
		sccipher_tobe = c->list[j];
		break;
	    }
	}
	if (sccipher_tobe)
	if (!c) {
	    warn = 1;
	} else {
	    for (j = 0; j < c->nciphers; j++) {
		if (in_commasep_string(c->list[j]->name, str, len)) {
		    sccipher_tobe = c->list[j];
		    break;
		}
	    }
	}
	if (sccipher_tobe) {
	    if (warn)
		askcipher(sccipher_tobe->name, 2);
	    break;
	}
    }
    ssh2_pkt_getstring(&str, &len);    /* client->server mac */
    for (i = 0; i < nmacs; i++) {
	if (in_commasep_string(maclist[i]->name, str, len)) {
	    csmac_tobe = maclist[i];
	    break;
	}