-
Notifications
You must be signed in to change notification settings - Fork 0
/
userPass.ts
80 lines (73 loc) · 2.06 KB
/
userPass.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
import { AUTHMODES } from '../../../helper/constants'
import { AuthMethod } from '../../../helper/authMethod'
import Connection from '../../../helper/connection'
import { State } from '../../../helper/state'
import { RequestState } from '../../state/socks5'
/**
* 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) => {
const authState = new UserPassReqState(connection)
authState.handler = handler
connection.transitionTo(authState)
},
}
}
/**
* The UserPassReqState class negotiates with the user and,
* authenticates the user's credentials
* @remarks
* References: {@link https://www.rfc-editor.org/rfc/rfc1929}
*/
class UserPassReqState extends State {
/**
* Handler function
*/
public handler?: (user: string, pass: string) => boolean
/**
* SOCKS version
*/
private version?: Buffer
/**
* Username
*/
private username?: string
/**
* Password
*/
private password?: string
/**
* Parse request
* @returns void
*/
parse(): void {
this.version = this.context.read(1)
const ulen = this.context.read(1)
this.username = this.context.read(ulen.readInt8()).toString()
const plen = this.context.read(1)
this.password = this.context.read(plen.readInt8()).toString()
}
/**
* Reply to the user with a proper response
* @returns void
*/
reply(): void {
if (this.handler && this.username && this.password && this.version) {
if (this.handler(this.username.toString(), this.password.toString())) {
this.context.socket.write(Buffer.from([this.version.readInt8(), 0x00]))
this.context.transitionTo(new RequestState(this.context))
} else {
this.context.socket.write(Buffer.from([this.version.readUInt8(), 0xff]))
this.context.close()
}
}
}
}