mirror of
https://github.com/swc-project/swc.git
synced 2024-12-22 13:11:31 +03:00
73 lines
2.0 KiB
TypeScript
73 lines
2.0 KiB
TypeScript
|
// Loaded from https://deno.land/x/mysql/src/auth_plugin/caching_sha2_password.ts
|
||
|
|
||
|
|
||
|
import { xor } from "../util.ts";
|
||
|
import { ReceivePacket } from "../packets/packet.ts";
|
||
|
import { encryptWithPublicKey } from "./crypt.ts";
|
||
|
|
||
|
interface handler {
|
||
|
done: boolean;
|
||
|
quickRead?: boolean;
|
||
|
next?: (packet: ReceivePacket) => any;
|
||
|
data?: Uint8Array;
|
||
|
}
|
||
|
|
||
|
let scramble: Uint8Array, password: string;
|
||
|
function start(scramble_: Uint8Array, password_: string): handler {
|
||
|
scramble = scramble_;
|
||
|
password = password_;
|
||
|
return { done: false, next: authMoreResponse };
|
||
|
}
|
||
|
function authMoreResponse(packet: ReceivePacket): handler {
|
||
|
const enum AuthStatusFlags {
|
||
|
FullAuth = 0x04,
|
||
|
FastPath = 0x03,
|
||
|
}
|
||
|
const REQUEST_PUBLIC_KEY = 0x02;
|
||
|
const statusFlag = packet.body.skip(1).readUint8();
|
||
|
let authMoreData, done = true, next, quickRead = false;
|
||
|
if (statusFlag === AuthStatusFlags.FullAuth) {
|
||
|
authMoreData = new Uint8Array([REQUEST_PUBLIC_KEY]);
|
||
|
done = false;
|
||
|
next = encryptWithKey;
|
||
|
}
|
||
|
if (statusFlag === AuthStatusFlags.FastPath) {
|
||
|
done = false;
|
||
|
quickRead = true;
|
||
|
next = terminate;
|
||
|
}
|
||
|
return { done, next, quickRead, data: authMoreData };
|
||
|
}
|
||
|
|
||
|
function encryptWithKey(packet: ReceivePacket): handler {
|
||
|
const publicKey = parsePublicKey(packet);
|
||
|
const len = password.length;
|
||
|
let passwordBuffer: Uint8Array = new Uint8Array(len + 1);
|
||
|
for (let n = 0; n < len; n++) {
|
||
|
passwordBuffer[n] = password.charCodeAt(n);
|
||
|
}
|
||
|
passwordBuffer[len] = 0x00;
|
||
|
|
||
|
const encryptedPassword = encrypt(passwordBuffer, scramble, publicKey);
|
||
|
return { done: false, next: terminate, data: encryptedPassword };
|
||
|
}
|
||
|
|
||
|
function parsePublicKey(packet: ReceivePacket): string {
|
||
|
return packet.body.skip(1).readNullTerminatedString();
|
||
|
}
|
||
|
function encrypt(
|
||
|
password: Uint8Array,
|
||
|
scramble: Uint8Array,
|
||
|
key: string,
|
||
|
): Uint8Array {
|
||
|
const stage1 = xor(password, scramble);
|
||
|
const encrypted = encryptWithPublicKey(key, stage1);
|
||
|
return encrypted;
|
||
|
}
|
||
|
|
||
|
function terminate() {
|
||
|
return { done: true };
|
||
|
}
|
||
|
|
||
|
export { start };
|