📄 proxy.c
字号:
socketError("recv()", WSAGetLastError());
return PROXY_ERROR;
}
/* size check */
if (ret != sizeof(rep)) {
proxyError(PE_DATA);
return PROXY_ERROR;
}
/* eval server reply */
switch (rep.status)
{
case S5_AUTH_UP_SUCCESS:
return socks5SendConnectRequest();
case S5_AUTH_UP_EFAILED:
proxyError(PE_AUTH);
break;
default:
proxyError(PE_DATA);
break;
}
return PROXY_ERROR;
}
/* Send the SOCKS5 supported autentication methods
*/
static int socks5SendAuthMethods(void)
{
int ret;
struct s5AuthMethodReq req;
/* set supported autentication methods (only username/password) */
req.version = S5_VERSION;
req.nmethods = 1;
req.methods[0] = S5_AUTH_USERPASSWORD;
/* send to server */
ret = send(socketGetHandle(), (char *) &req, sizeof(req), 0);
if (ret == -1) {
socketError("send()", WSAGetLastError());
return PROXY_ERROR;
}
handlerIndex++;
return PROXY_OK;
}
/* State machine for SOCKS5
*/
static StateHandler *socks5Handler[] = {
socks5SendAuthMethods,
socks5GetAuthMethod,
socks5GetAuthReply,
socks5GetConnectReply
};
/* Send an HTTP Proxy connect request
*/
static int httpSendConnectRequest(void)
{
int ret;
char buf[256];
sprintf(buf, "CONNECT %s:%d HTTP/1.0\r\n\r\n", dstHost, dstPort);
ret = send(socketGetHandle(), buf, strlen(buf), 0);
if (ret == -1) {
socketError("send()", WSAGetLastError());
return PROXY_ERROR;
}
handlerIndex++;
return PROXY_OK;
}
/* Get HTTP Proxy reply from server
*/
static int httpGetConnectReply(void)
{
int i, ret;
char ch, msg[128];
char buf[256], *http, *reply, *desc;
for ( i = 0 ; ; )
{
ret = recv(socketGetHandle(), &ch, 1, 0);
if (ret == -1) {
socketError("recv()", WSAGetLastError());
return PROXY_ERROR;
}
if (ch == '\n') {
buf[i] = 0;
break;
}
else if (ch != '\r') {
if (i < (sizeof(buf) - 1)) {
buf[i++] = ch;
}
}
}
http = buf;
reply = strchr(http, ' ');
if (!reply) {
proxyError(PE_DATA);
return PROXY_ERROR;
}
*reply++ = '\0';
desc = strchr(reply, ' ');
if (desc) {
*desc++ = '\0';
}
if (!strcmp(reply, "200")) {
emptyLine = TRUE;
handlerIndex++;
return PROXY_OK;
}
sprintf(msg, errorString[PE_HTTP], http, reply, desc);
MessageBox(telnetGetWnd(), msg, telnetAppName(), MB_APPLMODAL | MB_ICONHAND | MB_OK);
return PROXY_ERROR;
}
/* Skip HTTP Proxy mime header
*/
static int httpSkipMimeHeader(void)
{
int ret;
char ch;
while (1) {
ret = recv(socketGetHandle(), &ch, 1, 0);
if (ret == -1) {
if (WSAGetLastError() == WSAEWOULDBLOCK) {
return PROXY_OK;
}
socketError("recv()", WSAGetLastError());
return PROXY_ERROR;
}
if (ch == '\n') {
if (emptyLine) {
break;
}
emptyLine = TRUE;
}
else if (ch != '\r') {
emptyLine = FALSE;
}
}
return PROXY_CONNECTED;
}
/* State machine for HTTP Proxy
*/
static StateHandler *httpHandler[] = {
httpSendConnectRequest,
httpGetConnectReply,
httpSkipMimeHeader,
};
/* Handle Proxy protocols
*/
int proxyProtocolHandler(void)
{
return curProto[handlerIndex]();
}
/* Start the request
*/
int proxyStartRequest(char *host, int port)
{
handlerIndex = 0;
dstPort = port;
memset(dstHost, 0, sizeof(dstHost));
strncpy(dstHost, host, sizeof(dstHost)-1);
switch (proxy.protocol)
{
case PP_SOCKS4:
case PP_SOCKS4A:
curProto = socks4Handler;
break;
case PP_SOCKS5:
curProto = socks5Handler;
break;
case PP_HTTP:
curProto = httpHandler;
break;
}
return proxyProtocolHandler();
}
/* Remote end has closed the connection with a request in progress
*/
void proxyRemoteHasClosed(void) {
proxyError(PE_CLOSE);
}
/* Enable ok button only if hostname and port have text
*/
static void proxyDlgEnableOk(HWND dlg)
{
int len;
BOOL enabled = TRUE;
char port[PORT_LEN];
char host[HOSTNAME_LEN];
int sel;
sel = (int)SendDlgItemMessage(dlg, IDC_PROXY_PROTOCOL, CB_GETCURSEL, 0, 0);
if (sel != PP_DISABLED)
{
len = GetDlgItemText(dlg, IDC_PROXY_PORT, port, sizeof(port));
if (len > 0) {
len = GetDlgItemText(dlg, IDC_PROXY_HOSTNAME, host, sizeof(host));
if (len > 0) {
if (!isNonBlank(port) || !isNonBlank(host)) {
enabled = FALSE;
}
} else {
enabled = FALSE;
}
} else {
enabled = FALSE;
}
}
EnableWindow(GetDlgItem(dlg, IDOK), enabled);
}
/* Enable/disable edit controls
*/
static void proxyDlgEnableEdit(HWND dlg)
{
int protocol;
protocol = (int)SendDlgItemMessage(dlg, IDC_PROXY_PROTOCOL, CB_GETCURSEL, 0, 0);
EnableWindow(GetDlgItem(dlg, IDC_PROXY_HOSTNAME), protocol != PP_DISABLED);
EnableWindow(GetDlgItem(dlg, IDC_PROXY_USERID), protocol != PP_DISABLED && protocol != PP_HTTP);
EnableWindow(GetDlgItem(dlg, IDC_PROXY_PASSWORD), protocol == PP_SOCKS5);
EnableWindow(GetDlgItem(dlg, IDC_PROXY_PORT), protocol != PP_DISABLED);
}
/* Proxy dialog proc
*/
BOOL CALLBACK proxyDlgProc(HWND dlg, UINT message, WPARAM wparam, LPARAM lparam)
{
switch (message)
{
case WM_INITDIALOG:
/* Flag that we have created the dialog and register the dialog window handle.
*/
hProxyDlg = dlg;
dialogRegister(dlg);
/* Initialise the dialog controls
*/
SendDlgItemMessage(dlg, IDC_PROXY_PROTOCOL, CB_ADDSTRING, 0, (LPARAM) disabledStr);
SendDlgItemMessage(dlg, IDC_PROXY_PROTOCOL, CB_ADDSTRING, 0, (LPARAM) socks4Str);
SendDlgItemMessage(dlg, IDC_PROXY_PROTOCOL, CB_ADDSTRING, 0, (LPARAM) socks4aStr);
SendDlgItemMessage(dlg, IDC_PROXY_PROTOCOL, CB_ADDSTRING, 0, (LPARAM) socks5Str);
SendDlgItemMessage(dlg, IDC_PROXY_PROTOCOL, CB_ADDSTRING, 0, (LPARAM) httpStr);
SendDlgItemMessage(dlg, IDC_PROXY_PROTOCOL, CB_SETCURSEL, proxy.protocol, 0);
proxyDlgEnableEdit(dlg);
proxyDlgEnableOk(dlg);
SetDlgItemText(dlg, IDC_PROXY_PORT, proxy.port);
SetDlgItemText(dlg, IDC_PROXY_HOSTNAME, proxy.host);
SetDlgItemText(dlg, IDC_PROXY_USERID, proxy.username);
SetDlgItemText(dlg, IDC_PROXY_PASSWORD, proxy.password);
return TRUE;
case WM_COMMAND:
switch (LOWORD(wparam))
{
case IDC_PROXY_HOSTNAME:
case IDC_PROXY_PORT:
#ifdef WIN32
if (HIWORD(wparam) != EN_CHANGE)
break;
#else
if (HIWORD(lparam) != EN_CHANGE)
break;
#endif
proxyDlgEnableOk(dlg);
break;
case IDC_PROXY_PROTOCOL:
#ifdef WIN32
if (HIWORD(wparam) != CBN_SELCHANGE)
break;
#else
if (HIWORD(lparam) != CBN_SELCHANGE)
break;
#endif
proxyDlgEnableOk(dlg);
proxyDlgEnableEdit(dlg);
break;
case IDOK:
/* Read all dialog controls into the current session
*/
proxy.protocol = SendDlgItemMessage(dlg, IDC_PROXY_PROTOCOL, CB_GETCURSEL, 0, 0);
GetDlgItemText(dlg, IDC_PROXY_PORT, proxy.port, sizeof(proxy.port));
GetDlgItemText(dlg, IDC_PROXY_HOSTNAME, proxy.host, sizeof(proxy.host));
GetDlgItemText(dlg, IDC_PROXY_USERID, proxy.username, sizeof(proxy.username));
GetDlgItemText(dlg, IDC_PROXY_PASSWORD, proxy.password, sizeof(proxy.password));
case IDCANCEL:
/* Destroy the dialog and unregister the dialog handle.
*/
DestroyWindow(dlg);
dialogUnRegister(dlg);
hProxyDlg = NULL;
return TRUE;
}
}
return FALSE;
}
/* display the Proxy dialog
*/
void showProxyDialog(HINSTANCE instance, HWND wnd)
{
if (!hProxyDlg) {
CreateDialog(instance, MAKEINTRESOURCE(IDD_PROXY_DIALOG), wnd, proxyDlgProc);
}
}
/* return TRUE if Proxy is enabled
*/
BOOL proxyEnabled(void) {
return (proxy.protocol != PP_DISABLED);
}
/* return the current Proxy host
*/
char* proxyGetHost(void) {
return proxy.host;
}
/* return the current Proxy port
*/
char* proxyGetPort(void) {
return proxy.port;
}
/* return TRUE if destination hostname can be resolved by proxy server
*/
BOOL proxySupportHostname(void) {
return (proxy.protocol != PP_SOCKS4);
}
/* Get proxy parameters from .ini file
*/
void proxyGetProfile(void)
{
/* Get current proxy parameters */
GetPrivateProfileString(proxyStr, hostStr, "", proxy.host, sizeof(proxy.host), telnetIniFile());
GetPrivateProfileString(proxyStr, portStr, "1080", proxy.port, sizeof(proxy.port), telnetIniFile());
proxy.protocol = GetPrivateProfileInt(proxyStr, protocolStr, PP_DISABLED, telnetIniFile());
if ((proxy.protocol < PP_DISABLED) || (proxy.protocol > PP_HTTP)) {
proxy.protocol = PP_DISABLED;
}
GetPrivateProfileString(proxyStr, usernameStr, "", proxy.username, sizeof(proxy.username), telnetIniFile());
GetPrivateProfileString(proxyStr, passwordStr, "", proxy.password, sizeof(proxy.password), telnetIniFile());
}
/* Save proxy parameters to .ini file
*/
void proxySaveProfile(void)
{
char str[20];
/* Save current socks parameters */
sprintf(str, "%d", proxy.protocol);
WritePrivateProfileString(proxyStr, protocolStr, str, telnetIniFile());
WritePrivateProfileString(proxyStr, hostStr, proxy.host, telnetIniFile());
WritePrivateProfileString(proxyStr, usernameStr, proxy.username, telnetIniFile());
WritePrivateProfileString(proxyStr, passwordStr, proxy.password, telnetIniFile());
WritePrivateProfileString(proxyStr, portStr, proxy.port, telnetIniFile());
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -