📄 ckctel.c
字号:
fwdx_tn_sb( unsigned char * sb, int n )#elsefwdx_tn_sb( sb, n ) unsigned char * sb; int n;#endif /* CK_ANSIC */{ unsigned short hchannel, nchannel; unsigned char * p; int i; int rc = -1; /* check to ensure we have negotiated Forward X */ if ( sstelnet && !TELOPT_ME(TELOPT_FORWARD_X) || !sstelnet && !TELOPT_U(TELOPT_FORWARD_X) ) { debug(F100,"fwdx_tn_sb() not negotiated","",0); return(0); }#ifdef CK_SSL if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows) { return(0); }#endif /* CK_SSL */ switch (sb[0]) { case FWDX_SCREEN: if (sstelnet && n == 4) rc = fwdx_create_listen_socket(sb[1]); break; case FWDX_OPEN: if ( !sstelnet && n >= 5 ) { p = (unsigned char *) &nchannel; i = 1; /* IAC quoting has been stripped in tn_sb() */ p[0] = sb[i++]; p[1] = sb[i++]; hchannel = ntohs(nchannel); rc = fwdx_open_client_channel(hchannel); if ( rc < 0 ) { /* Failed; Send CLOSE channel */ fwdx_send_close(hchannel); rc = 0; /* Do not consider this to be a telnet error */ }#ifdef NT if ( !TELOPT_SB(TELOPT_FORWARD_X).forward_x.thread_started ) { ckThreadBegin( &fwdx_thread,32655, 0, FALSE, 0 ) ; TELOPT_SB(TELOPT_FORWARD_X).forward_x.thread_started = 1; }#endif /* NT */ } break; case FWDX_CLOSE: p = (unsigned char *) &nchannel; i = 1; /* IAC quoting has been stripped in tn_sb() */ p[0] = sb[i++]; p[1] = sb[i++]; hchannel = ntohs(nchannel); fwdx_close_channel(hchannel); rc = 0; /* no errors when closing */ break; case FWDX_DATA: p = (unsigned char *) &nchannel; i = 1; /* IAC quoting has been stripped in tn_sb() */ p[0] = sb[i++]; p[1] = sb[i++]; hchannel = ntohs(nchannel); rc = fwdx_send_xauth_to_xserver(hchannel,(char *)&sb[3],n-5); if ( rc >= 0 && n-5-rc > 0) { rc = fwdx_write_data_to_channel(hchannel,(char *)&sb[3+rc],n-5-rc); if ( rc < 0 ) { /* Failed; Send CLOSE channel */ rc = fwdx_send_close(hchannel); } } break; case FWDX_OPTIONS: if ( sstelnet ) {#ifndef FWDX_SERVER rc = 0;#else rc = fwdx_server_accept_options((char*)&sb[2],n-3);#endif } else { rc = fwdx_client_reply_options((char *)&sb[2],n-3); if ( rc >= 0 ) { rc = tn_sndfwdx(); } } break; case FWDX_OPT_DATA: switch ( sb[1] ) { default: rc = 0; /* we don't recognize, not an error */ } break; case FWDX_XOFF: case FWDX_XON: if ( !sstelnet ) { p = (unsigned char *) &nchannel; i = 1; /* IAC quoting has been stripped in tn_sb() */ p[0] = sb[i++]; p[1] = sb[i++]; hchannel = ntohs(nchannel); TELOPT_SB(TELOPT_FORWARD_X).forward_x.channel[hchannel].suspend = (sb[0] == FWDX_XOFF); rc = 0; } break; } return(rc < 0 ? -1 : 0);}int#ifdef CK_ANSICfwdx_send_xauth_to_xserver(int channel, unsigned char * data, int len)#elsefwdx_send_xauth_to_xserver(channel, data, len) int channel; unsigned char * data; int len;#endif /* CK_ANSIC */{ int name_len, data_len, i; for (i = 0; i < MAXFWDX ; i++) { if (TELOPT_SB(TELOPT_FORWARD_X).forward_x.channel[i].id == channel) break; } if ( i == MAXFWDX ) goto auth_err; if (!TELOPT_SB(TELOPT_FORWARD_X).forward_x.channel[i].need_to_send_xauth) return(0); if (len < 12) goto auth_err; /* Parse the lengths of variable-length fields. */ if (data[0] == 0x42) { /* byte order MSB first. */ /* Xauth packets appear to always have this format */ if ( data[1] != 0x00 || data[2] != 0x00 || data[3] != 0x0B || data[4] != 0x00 || data[5] != 0x00 ) goto auth_err; name_len = (data[6] << 8) + data[7]; data_len = (data[8] << 8) + data[9]; } else if (data[0] == 0x6c) { /* Byte order LSB first. */ /* Xauth packets appear to always have this format */ if ( data[1] != 0x00 || data[2] != 0x0B || data[3] != 0x00 || data[4] != 0x00 || data[5] != 0x00 ) goto auth_err; name_len = data[6] + (data[7] << 8); data_len = data[8] + (data[9] << 8); } else { /* bad byte order byte */ goto auth_err; } /* Check if the whole packet is in buffer. */ if (len < 12 + ((name_len + 3) & ~3) + ((data_len + 3) & ~3)) goto auth_err; /* If the Telnet Server allows a real Xauth message to be sent */ /* Then let the message be processed by the Xserver. */ if (name_len + data_len > 0) { TELOPT_SB(TELOPT_FORWARD_X).forward_x.channel[i].need_to_send_xauth = 0; return(0); } else /* If an empty Xauth message was received. We are going to */ /* send our own Xauth message using the real Xauth data. And */ /* then send any other data in the buffer. */ { int c, err, dpynum, scrnum, family, sb_len; char *display, *host = NULL, *rest = NULL; unsigned char *sb, *p; /* parse the local DISPLAY env var */ display = getenv("DISPLAY"); if ( !display ) display = "127.0.0.1:0.0"; if (fwdx_parse_displayname(display, &family, &host, &dpynum, &scrnum, &rest)) { char * disp_no = ckitoa(dpynum); /* should be unsigned */ if (family == FamilyLocal) { /* call with address = "<local host name>" */ char address[300] = "localhost"; gethostname(address, sizeof(address) - 1); real_xauth = XauGetAuthByAddr(family, strlen(address), address, strlen(disp_no), disp_no, 0, NULL); } else if (family == FamilyInternet) { /* call with address = 4 bytes numeric ip addr (MSB) */ struct hostent *hi; if (hi = gethostbyname(host)) real_xauth = XauGetAuthByAddr(family, 4, hi->h_addr, strlen(disp_no), disp_no, 0, NULL); } } if (host) free(host); if (rest) free(rest); if (!real_xauth) { TELOPT_SB(TELOPT_FORWARD_X).forward_x.channel[i].need_to_send_xauth = 0; return(0); } if (!strncmp(real_xauth->name, "MIT-MAGIC-COOKIE-1", real_xauth->name_length)) { char msg[64]; name_len = real_xauth->name_length; data_len = 16; if ( data[0] == 0x42 ) { msg[0] = 0x42; /* MSB order */ msg[1] = msg[2] = 0; msg[3] = 0x0B; msg[4] = msg[5] = 0; msg[6] = (name_len >> 8); msg[7] = (name_len & 0xFF); msg[8] = (data_len >> 8); msg[9] = (data_len & 0xFF); } else { msg[0] = 0x6c; /* LSB order */ msg[1] = 0; msg[2] = 0x0B; msg[3] = msg[4] = msg[5] = 0; msg[6] = (name_len & 0xFF); msg[7] = (name_len >> 8); msg[8] = (data_len & 0xFF); msg[9] = (data_len >> 8); } msg[10] = msg[11] = 0; memcpy(&msg[12],real_xauth->name,18); msg[30] = msg[31] = 0; memcpy(&msg[32],real_xauth->data,16); if (fwdx_write_data_to_channel(channel,(char *)msg,48) < 0) { TELOPT_SB(TELOPT_FORWARD_X).forward_x.channel[i].need_to_send_xauth = 0; return(-1); } else { TELOPT_SB(TELOPT_FORWARD_X).forward_x.channel[i].need_to_send_xauth = 0; return(12); } } else { TELOPT_SB(TELOPT_FORWARD_X).forward_x.channel[i].need_to_send_xauth = 0; return(0); /* we do not know how to handle this type yet */ } } auth_err: debug(F100,"fwdx_send_xauth_to_xserver error","",0); return(-1);}#ifdef COMMENTint#ifdef CK_ANSICfwdx_authorize_channel(int channel, unsigned char * data, int len)#elsefwdx_authorize_channel(channel, data, len) int channel; unsigned char * data; int len;#endif /* CK_ANSIC */{ /* XXX maybe we should have some retry handling if not the whole first * authorization packet arrives complete */ if ( !TELOPT_SB(TELOPT_FORWARD_X).forward_x.channel[channel].authorized ) { int name_len, data_len; if (len < 12) goto auth_err; /* Parse the lengths of variable-length fields. */ if (data[0] == 0x42) { /* byte order MSB first. */ /* Xauth packets appear to always have this format */ if ( data[1] != 0x00 || data[2] != 0x00 || data[3] != 0x0B || data[4] != 0x00 || data[5] != 0x00 ) goto auth_err; name_len = (data[6] << 8) + data[7]; data_len = (data[8] << 8) + data[9]; } else if (data[0] == 0x6c) { /* Byte order LSB first. */ /* Xauth packets appear to always have this format */ if ( data[1] != 0x00 || data[2] != 0x0B || data[3] != 0x00 || data[4] != 0x00 || data[5] != 0x00 ) goto auth_err; name_len = data[6] + (data[7] << 8); data_len = data[8] + (data[9] << 8); } else { /* bad byte order byte */ goto auth_err; } /* Check if authentication protocol matches. */ if (name_len != fake_xauth.name_length || memcmp(data + 12, fake_xauth.name, name_len) != 0) { /* connection uses different authentication protocol */ goto auth_err; } /* Check if authentication data matches our fake data. */ if (data_len != fake_xauth.data_length || memcmp(data + 12 + ((name_len + 3) & ~3), fake_xauth.data, fake_xauth.data_length) != 0) { /* auth data does not match fake data */ goto auth_err; } /* substitute the fake data with real data if we have any */ if (real_xauth && real_xauth->data) memcpy(data + 12 + ((name_len + 3) & ~3), real_xauth->data, data_len); TELOPT_SB(TELOPT_FORWARD_X).forward_x.channel[channel].authorized = 1; } return(0); auth_err: return(-1);}#endif /* COMMENT */int#ifdef CK_ANSICfwdx_send_close(int channel)#elsefwdx_send_close(channel) int channel;#endif /* CK_ANSIC */{ unsigned short nchannel; int i,rc; CHAR * p;#ifdef CK_SSL if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows) { return(0); }#endif /* CK_SSL */ nchannel = htons(channel); p = (unsigned char *) &nchannel; i = 0; sb_out[i++] = (CHAR) IAC; /* I Am a Command */ sb_out[i++] = (CHAR) SB; /* Subnegotiation */ sb_out[i++] = TELOPT_FORWARD_X; /* Forward X */ sb_out[i++] = FWDX_CLOSE; /* Open */ sb_out[i++] = p[0]; /* First Byte of Channel */ if ( p[0] == IAC ) sb_out[i++] = IAC; sb_out[i++] = p[1]; /* Second Byte of Channel */ if ( p[1] == IAC ) sb_out[i++] = IAC; sb_out[i++] = (CHAR) IAC; /* End of Subnegotiation */ sb_out[i++] = (CHAR) SE; /* marked by IAC SE */#ifdef DEBUG if (deblog || tn_deb || debses) { ckmakxmsg(fwdx_msg_out,TN_MSG_LEN,"TELNET SENT SB ", TELOPT(TELOPT_FORWARD_X), " CLOSE CHANNEL=",ckitoa(channel)," IAC SE", NULL,NULL,NULL,NULL,NULL,NULL,NULL ); }#endif /* DEBUG */#ifdef OS2 RequestTelnetMutex( SEM_INDEFINITE_WAIT );#endif#ifdef DEBUG debug(F100,fwdx_msg_out,"",0); if (tn_deb || debses) tn_debug(fwdx_msg_out);#endif /* DEBUG */ rc = (ttol((CHAR *)sb_out,i) < 0); /* Send it. */#ifdef OS2 ReleaseTelnetMutex();#endif if (rc) return(-1); return(0);}int#ifdef CK_ANSICfwdx_send_open(int channel)#else /* CK_ANSIC */fwdx_send_open(channel) int channel;#endif /* CK_ANSIC */{ unsigned short nchannel; int i, rc; CHAR * p;#ifdef CK_SSL if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows) { return(0); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -