📄 encrypt.c
字号:
if (encrypt_debug_mode) printf(">>>%s: He is supporting %s (%d)\r\n", Name, ENCTYPE_NAME(type), type); if ((type < ENCTYPE_CNT) && (I_SUPPORT_ENCRYPT & typemask(type))) { remote_supports_decrypt |= typemask(type); if (use_type == 0) use_type = type; } } if (use_type) { ep = findencryption(use_type); if (!ep) return; type = ep->start ? (*ep->start)(DIR_ENCRYPT, Server) : 0; if (encrypt_debug_mode) printf(">>>%s: (*ep->start)() returned %d\r\n", Name, type); if (type < 0) return; encrypt_mode = use_type; if (type == 0) encrypt_start_output(use_type); }} voidencrypt_is(data, cnt) unsigned char *data; int cnt;{ Encryptions *ep; register int type, ret; if (--cnt < 0) return; type = *data++; if (type < ENCTYPE_CNT) remote_supports_encrypt |= typemask(type); if (!(ep = finddecryption(type))) { if (encrypt_debug_mode) printf(">>>%s: Can't find type %s (%d) for initial negotiation\r\n", Name, ENCTYPE_NAME_OK(type) ? ENCTYPE_NAME(type) : "(unknown)", type); return; } if (!ep->is) { if (encrypt_debug_mode) printf(">>>%s: No initial negotiation needed for type %s (%d)\r\n", Name, ENCTYPE_NAME_OK(type) ? ENCTYPE_NAME(type) : "(unknown)", type); ret = 0; } else { ret = (*ep->is)(data, cnt); if (encrypt_debug_mode) printf("(*ep->is)(%x, %d) returned %s(%d)\n", data, cnt, (ret < 0) ? "FAIL " : (ret == 0) ? "SUCCESS " : "MORE_TO_DO ", ret); } if (ret < 0) { autodecrypt = 0; } else { decrypt_mode = type; if (ret == 0 && autodecrypt) encrypt_send_request_start(); }} voidencrypt_reply(data, cnt) unsigned char *data; int cnt;{ Encryptions *ep; register int ret, type; if (--cnt < 0) return; type = *data++; if (!(ep = findencryption(type))) { if (encrypt_debug_mode) printf(">>>%s: Can't find type %s (%d) for initial negotiation\r\n", Name, ENCTYPE_NAME_OK(type) ? ENCTYPE_NAME(type) : "(unknown)", type); return; } if (!ep->reply) { if (encrypt_debug_mode) printf(">>>%s: No initial negotiation needed for type %s (%d)\r\n", Name, ENCTYPE_NAME_OK(type) ? ENCTYPE_NAME(type) : "(unknown)", type); ret = 0; } else { ret = (*ep->reply)(data, cnt); if (encrypt_debug_mode) printf("(*ep->reply)(%x, %d) returned %s(%d)\n", data, cnt, (ret < 0) ? "FAIL " : (ret == 0) ? "SUCCESS " : "MORE_TO_DO ", ret); } if (encrypt_debug_mode) printf(">>>%s: encrypt_reply returned %d\n", Name, ret); if (ret < 0) { autoencrypt = 0; } else { encrypt_mode = type; if (ret == 0 && autoencrypt) encrypt_start_output(type); }}/* * Called when a ENCRYPT START command is received. */ voidencrypt_start(data, cnt) unsigned char *data; int cnt;{ Encryptions *ep; if (!decrypt_mode) { /* * Something is wrong. We should not get a START * command without having already picked our * decryption scheme. Send a REQUEST-END to * attempt to clear the channel... */ printf("%s: Warning, Cannot decrypt input stream!!!\r\n", Name); encrypt_send_request_end(); return; } if (ep = finddecryption(decrypt_mode)) { decrypt_input = ep->input; if (encrypt_verbose) printf("[ Input is now decrypted with type %s ]\r\n", ENCTYPE_NAME(decrypt_mode)); if (encrypt_debug_mode) printf(">>>%s: Start to decrypt input with type %s\r\n", Name, ENCTYPE_NAME(decrypt_mode)); } else { printf("%s: Warning, Cannot decrypt type %s (%d)!!!\r\n", Name, ENCTYPE_NAME_OK(decrypt_mode) ? ENCTYPE_NAME(decrypt_mode) : "(unknown)", decrypt_mode); encrypt_send_request_end(); }} voidencrypt_session_key(key, server) Session_Key *key; int server;{ Encryptions *ep = encryptions; havesessionkey = 1; while (ep->type) { if (ep->session) (*ep->session)(key, server);#ifdef notdef if (!encrypt_output && autoencrypt && !server) encrypt_start_output(ep->type); if (!decrypt_input && autodecrypt && !server) encrypt_send_request_start();#endif ++ep; }}/* * Called when ENCRYPT END is received. */ voidencrypt_end(){ decrypt_input = 0; if (encrypt_debug_mode) printf(">>>%s: Input is back to clear text\r\n", Name); if (encrypt_verbose) printf("[ Input is now clear text ]\r\n");}/* * Called when ENCRYPT REQUEST-END is received. */ voidencrypt_request_end(){ encrypt_send_end();}/* * Called when ENCRYPT REQUEST-START is received. If we receive * this before a type is picked, then that indicates that the * other side wants us to start encrypting data as soon as we * can. */ voidencrypt_request_start(data, cnt) unsigned char *data; int cnt;{ if (encrypt_mode == 0) { if (Server) autoencrypt = 1; return; } encrypt_start_output(encrypt_mode);}static unsigned char str_keyid[(MAXKEYLEN*2)+5] = { IAC, SB, TELOPT_ENCRYPT };encrypt_enc_keyid(keyid, len) unsigned char *keyid; int len;{ encrypt_keyid(&ki[1], keyid, len);}encrypt_dec_keyid(keyid, len) unsigned char *keyid; int len;{ encrypt_keyid(&ki[0], keyid, len);}encrypt_keyid(kp, keyid, len) struct key_info *kp; unsigned char *keyid; int len;{ Encryptions *ep; unsigned char *strp, *cp; int dir = kp->dir; register int ret = 0; if (!(ep = (*kp->getcrypt)(*kp->modep))) { if (len == 0) return; kp->keylen = 0; } else if (len == 0) { /* * Empty option, indicates a failure. */ if (kp->keylen == 0) return; kp->keylen = 0; if (ep->keyid) (void)(*ep->keyid)(dir, kp->keyid, &kp->keylen); } else if ((len != kp->keylen) || (memcmp(keyid, kp->keyid, len) != 0)) { /* * Length or contents are different */ kp->keylen = len; memmove(kp->keyid, keyid, len); if (ep->keyid) (void)(*ep->keyid)(dir, kp->keyid, &kp->keylen); } else { if (ep->keyid) ret = (*ep->keyid)(dir, kp->keyid, &kp->keylen); if ((ret == 0) && (dir == DIR_ENCRYPT) && autoencrypt) encrypt_start_output(*kp->modep); return; } encrypt_send_keyid(dir, kp->keyid, kp->keylen, 0);} voidencrypt_send_keyid(dir, keyid, keylen, saveit) int dir; unsigned char *keyid; int keylen; int saveit;{ unsigned char *strp; str_keyid[3] = (dir == DIR_ENCRYPT) ? ENCRYPT_ENC_KEYID : ENCRYPT_DEC_KEYID; if (saveit) { struct key_info *kp = &ki[(dir == DIR_ENCRYPT) ? 0 : 1]; memmove(kp->keyid, keyid, keylen); kp->keylen = keylen; } for (strp = &str_keyid[4]; keylen > 0; --keylen) { if ((*strp++ = *keyid++) == IAC) *strp++ = IAC; } *strp++ = IAC; *strp++ = SE; net_write(str_keyid, strp - str_keyid); printsub('>', &str_keyid[2], strp - str_keyid - 2);} voidencrypt_auto(on) int on;{ if (on < 0) autoencrypt ^= 1; else autoencrypt = on ? 1 : 0;} voiddecrypt_auto(on) int on;{ if (on < 0) autodecrypt ^= 1; else autodecrypt = on ? 1 : 0;} voidencrypt_start_output(type) int type;{ Encryptions *ep; register unsigned char *p; register int i; if (!(ep = findencryption(type))) { if (encrypt_debug_mode) { printf(">>>%s: Can't encrypt with type %s (%d)\r\n", Name, ENCTYPE_NAME_OK(type) ? ENCTYPE_NAME(type) : "(unknown)", type); } return; } if (ep->start) { i = (*ep->start)(DIR_ENCRYPT, Server); if (encrypt_debug_mode) { printf(">>>%s: Encrypt start: %s (%d) %s\r\n", Name, (i < 0) ? "failed" : "initial negotiation in progress", i, ENCTYPE_NAME(type)); } if (i) return; } p = str_start + 3; *p++ = ENCRYPT_START; for (i = 0; i < ki[0].keylen; ++i) { if ((*p++ = ki[0].keyid[i]) == IAC) *p++ = IAC; } *p++ = IAC; *p++ = SE; net_write(str_start, p - str_start); net_encrypt(); printsub('>', &str_start[2], p - &str_start[2]); /* * If we are already encrypting in some mode, then * encrypt the ring (which includes our request) in * the old mode, mark it all as "clear text" and then * switch to the new mode. */ encrypt_output = ep->output; encrypt_mode = type; if (encrypt_debug_mode) printf(">>>%s: Started to encrypt output with type %s\r\n", Name, ENCTYPE_NAME(type)); if (encrypt_verbose) printf("[ Output is now encrypted with type %s ]\r\n", ENCTYPE_NAME(type));} voidencrypt_send_end(){ if (!encrypt_output) return; str_end[3] = ENCRYPT_END; net_write(str_end, sizeof(str_end)); net_encrypt(); printsub('>', &str_end[2], sizeof(str_end) - 2); /* * Encrypt the output buffer now because it will not be done by * netflush... */ encrypt_output = 0; if (encrypt_debug_mode) printf(">>>%s: Output is back to clear text\r\n", Name); if (encrypt_verbose) printf("[ Output is now clear text ]\r\n");} voidencrypt_send_request_start(){ register unsigned char *p; register int i; p = &str_start[3]; *p++ = ENCRYPT_REQSTART; for (i = 0; i < ki[1].keylen; ++i) { if ((*p++ = ki[1].keyid[i]) == IAC) *p++ = IAC; } *p++ = IAC; *p++ = SE; net_write(str_start, p - str_start); printsub('>', &str_start[2], p - &str_start[2]); if (encrypt_debug_mode) printf(">>>%s: Request input to be encrypted\r\n", Name);} voidencrypt_send_request_end(){ str_end[3] = ENCRYPT_REQEND; net_write(str_end, sizeof(str_end)); printsub('>', &str_end[2], sizeof(str_end) - 2); if (encrypt_debug_mode) printf(">>>%s: Request input to be clear text\r\n", Name);} voidencrypt_wait(){ register int encrypt, decrypt; if (encrypt_debug_mode) printf(">>>%s: in encrypt_wait\r\n", Name); if (!havesessionkey || !(I_SUPPORT_ENCRYPT & remote_supports_decrypt)) return; while (autoencrypt && !encrypt_output) if (telnet_spin()) return;} voidencrypt_debug(mode) int mode;{ encrypt_debug_mode = mode;} voidencrypt_gen_printsub(data, cnt, buf, buflen) unsigned char *data, *buf; int cnt, buflen;{ char tbuf[16], *cp; cnt -= 2; data += 2; buf[buflen-1] = '\0'; buf[buflen-2] = '*'; buflen -= 2;; for (; cnt > 0; cnt--, data++) { sprintf(tbuf, " %d", *data); for (cp = tbuf; *cp && buflen > 0; --buflen) *buf++ = *cp++; if (buflen <= 0) return; } *buf = '\0';} voidencrypt_printsub(data, cnt, buf, buflen) unsigned char *data, *buf; int cnt, buflen;{ Encryptions *ep; register int type = data[1]; for (ep = encryptions; ep->type && ep->type != type; ep++) ; if (ep->printsub) (*ep->printsub)(data, cnt, buf, buflen); else encrypt_gen_printsub(data, cnt, buf, buflen);}#endif /* ENCRYPTION */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -