-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
✨ feat: clinet (connect) in progress
- Loading branch information
Showing
36 changed files
with
465 additions
and
135 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
import Connection from '../../helper/connection' | ||
import { Handlers } from '../../helper/handlers' | ||
import Writable from '../../helper/writable' | ||
import { none } from './methods/none' | ||
import { SOCKSVERSIONS } from '../../helper/constants' | ||
import { MethodSelectionState } from '../state/socks5' | ||
|
||
/** | ||
* The Authenticator Class is responsible for resolving incoming | ||
* authentication requests specific for socks5 | ||
*/ | ||
class Authenticator { | ||
/** | ||
* Server acceptable methods | ||
*/ | ||
private readonly availableMethods: Handlers['auth'] | ||
|
||
/** | ||
* Corresponding connection | ||
*/ | ||
private readonly connection: Connection | ||
|
||
constructor(connection: Connection) { | ||
this.connection = connection | ||
if (connection.handlers.auth.length <= 0) { | ||
connection.handlers.auth.push(none()) | ||
} | ||
this.availableMethods = connection.handlers.auth | ||
} | ||
|
||
/** | ||
* Negotiates for authentication method with the user and authenticates users | ||
* @returns void | ||
*/ | ||
public authenticate(): void { | ||
const writable = new Writable() | ||
writable.push(SOCKSVERSIONS.socks5, this.availableMethods.length) | ||
for (const method of this.availableMethods) { | ||
writable.push(method.method) | ||
} | ||
this.connection.transitionTo(new MethodSelectionState(this.connection)) | ||
this.connection.write(writable) | ||
} | ||
} | ||
|
||
export default Authenticator |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import { AUTHMODES } from '../../../helper/constants' | ||
import { AuthMethod } from '../../../helper/authMethod' | ||
|
||
/** | ||
* No authentication method | ||
* @returns AuthMethod | ||
*/ | ||
export const none = (): AuthMethod => { | ||
return { | ||
method: AUTHMODES.none, | ||
authenticate: (connection) => { | ||
connection.handlers.req.connect(connection) | ||
}, | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import { AUTHMODES } from '../../../helper/constants' | ||
import { AuthMethod } from '../../../helper/authMethod' | ||
import Connection from '../../../helper/connection' | ||
|
||
/** | ||
* Extract user/pass from user authentication request and, | ||
* execute the handler function | ||
* @param handler - Check the authorization of user/pass | ||
* @returns AuthMethod | ||
*/ | ||
export const userPass = ( | ||
handler: (user: string, pass: string) => boolean | ||
): AuthMethod => { | ||
return { | ||
method: AUTHMODES.userPass, | ||
authenticate: (connection: Connection) => { | ||
console.log('hey userPass') | ||
}, | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
/** | ||
* The Client class is responsible for creating a TCP socket connection, | ||
* and communicate with a standard socks server | ||
*/ | ||
import net from 'net' | ||
import Event from '../helper/event' | ||
import Connection, { EventTypes } from '../helper/connection' | ||
import * as handlers from './handlers/index' | ||
import { Handlers } from '../helper/handlers' | ||
import Authenticator from './auth/authenticator' | ||
import Address from '../helper/address' | ||
|
||
export class Client { | ||
private readonly host: string | ||
private readonly port: number | ||
private readonly connectionListener: (() => void) | undefined | ||
/** | ||
* The main event object | ||
*/ | ||
private readonly event: Event<EventTypes> | ||
constructor( | ||
port: number, | ||
host: string, | ||
connectionListener: (() => void) | undefined | ||
) { | ||
this.host = host | ||
this.port = port | ||
this.event = new Event<EventTypes>() | ||
this.connectionListener = connectionListener | ||
} | ||
|
||
/** | ||
* Connect to the target host trough socks server | ||
* @param port - Server port | ||
* @param host - Server address | ||
* @param version - Server protocol version | ||
* @returns void | ||
*/ | ||
connect(port: number, host: string, version: 4 | 5) { | ||
const socket = net.connect(this.port, this.host, this.connectionListener) | ||
const connection = new Connection( | ||
this.event, | ||
socket, | ||
new Handlers({ | ||
connect: handlers.connect, | ||
associate: handlers.associate, | ||
bind: handlers.bind, | ||
}) | ||
) | ||
connection.version = version | ||
connection.address = new Address(port, host) | ||
if (version === 5) { | ||
const authenticator = new Authenticator(connection) | ||
authenticator.authenticate() | ||
} | ||
return socket | ||
} | ||
} | ||
|
||
/** | ||
* Open new connection and connect to server | ||
* @param port - Server port | ||
* @param host - Server address | ||
* @param connectionListener - Emitted when a new connection opens | ||
* @returns void | ||
*/ | ||
export const connect = ( | ||
port: number, | ||
host: string, | ||
connectionListener?: (() => void) | undefined | ||
) => { | ||
return new Client(port, host, connectionListener) | ||
} |
2 changes: 1 addition & 1 deletion
2
src/server/handlers/default/associate.ts → src/client/handlers/associate.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
src/server/handlers/default/bind.ts → src/client/handlers/bind.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
import { handler } from '../../helper/handler' | ||
import Writable from '../../helper/writable' | ||
import { COMMANDS } from '../../helper/constants' | ||
|
||
/** | ||
* Default implementation of connect | ||
* @returns void | ||
*/ | ||
export const connect = handler((info, socket) => { | ||
const writeable = new Writable() | ||
writeable.push(info.version) | ||
if (info.version === 5) { | ||
const addressBuff = info.address.toBuffer() | ||
if (info.address.type === 'domain') { | ||
writeable.push( | ||
COMMANDS.connect, | ||
0x00, | ||
addressBuff.type, | ||
addressBuff.host.length, | ||
addressBuff.host, | ||
addressBuff.port | ||
) | ||
} else { | ||
writeable.push( | ||
COMMANDS.connect, | ||
0x00, | ||
addressBuff.type, | ||
addressBuff.host, | ||
addressBuff.port | ||
) | ||
} | ||
socket.write(writeable.toBuffer()) | ||
socket.on('data', (data) => { | ||
console.log(data) | ||
socket.removeAllListeners('data') | ||
}) | ||
} | ||
}) |
File renamed without changes.
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
import { State } from '../../helper/state' | ||
/** | ||
* The MethodSelectionState negotiates | ||
* with the client about the proper authentication method | ||
* specific for socks5 | ||
* @remarks | ||
* References: {@link https://www.rfc-editor.org/rfc/rfc1928#section-3} | ||
*/ | ||
export class MethodSelectionState extends State { | ||
/** | ||
* users' suggested authentication methods | ||
*/ | ||
private method?: Buffer | ||
|
||
/** | ||
* Parse request and extracts user suggested authentication methods | ||
* @returns void | ||
*/ | ||
parse() { | ||
this.context.read(1) | ||
this.method = this.context.read(1) | ||
} | ||
|
||
/** | ||
* Continues to authenticate procedure with authenticator class | ||
* @returns void | ||
*/ | ||
reply() { | ||
this.context.socket.removeAllListeners('data') | ||
this.context.handlers.auth | ||
.find((method) => { | ||
if (this.method && method) { | ||
return method.method === this.method.readInt8() | ||
} | ||
}) | ||
?.authenticate(this.context) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
import Connection from './connection' | ||
|
||
export interface AuthMethod { | ||
method: number | ||
authenticate: (connection: Connection) => void | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import { AuthMethod } from './authMethod' | ||
import Connection from './connection' | ||
|
||
interface Req { | ||
connect: (connection: Connection) => void | ||
associate: (connection: Connection) => void | ||
bind: (connection: Connection) => void | ||
} | ||
|
||
/** | ||
* The Handlers class contains handler functions corresponding | ||
* to authentication and request (connect | associate | bind) | ||
*/ | ||
export class Handlers { | ||
public userId: (userId: string) => boolean | ||
public auth: AuthMethod[] | ||
public req: Req | ||
constructor(req: Req) { | ||
this.userId = () => true | ||
this.auth = [] | ||
this.req = req | ||
} | ||
} |
Oops, something went wrong.