-
Notifications
You must be signed in to change notification settings - Fork 140
Expand file tree
/
Copy pathCigPassword.vue
More file actions
140 lines (122 loc) · 3.4 KB
/
CigPassword.vue
File metadata and controls
140 lines (122 loc) · 3.4 KB
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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
<template>
<div>
<form id="cig-password" novalidate @submit.prevent="handleSubmit">
<div class="form-floating mb-3">
<label for="serial" class="form-label">GPON S/N in format GPONabc12345</label>
<input
v-model="serial"
type="text"
class="form-control"
placeholder="Serial Number"
name="serial"
id="serial"
required
pattern="[0-9A-Za-z]{4}[0-9A-Fa-f]{8}"
/>
<div class="invalid-feedback">Please provide a valid GPON S/N.</div>
</div>
<div class="mb-3">
<button type="submit" class="btn btn-primary">Generate!</button>
<label for="submit" class="form-label"
>Warning: this script is hosted on a third-party server.</label
>
</div>
<div class="form-floating mb-3">
<label for="username" class="form-label">Username</label>
<input
readonly
type="text"
class="form-control"
placeholder="Username"
name="username"
id="username"
:value="username"
/>
</div>
<div class="form-floating mb-3">
<label for="result" class="form-label">Password</label>
<input
readonly
class="form-control"
type="text"
id="result"
placeholder="Result"
v-model="result"
/>
</div>
</form>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import CryptoJS from 'crypto-js'
const props = defineProps<{
username?: string
}>()
const serial = ref('')
const result = ref('')
const validated = ref(false)
function hexToBytes(hex: string): Uint8Array {
const bytes = new Uint8Array(hex.length / 2)
for (let i = 0; i < hex.length; i += 2) {
bytes[i / 2] = parseInt(hex.substr(i, 2), 16)
}
return bytes
}
function cigpassword_gpon(
ont_serial: string,
ont_user: string,
length: number = 0,
xgspon: boolean = false
): string {
const hardcoded_key = '01030a1013051764c8061419b49d0500'
const hardcoded_seed =
'2345679abcdefghijkmnpqrstuvwxyzACDEFGHJKLMNPQRSTUVWXYZ'
let ont_vendor = ont_serial.substring(0, 4).toUpperCase()
let ont_id = ont_serial.substring(4).toLowerCase()
if (xgspon) {
ont_id = ont_id.toUpperCase()
}
let formatted_serial = `${ont_vendor}${ont_id}`
let key_bytes = new Uint8Array(
hardcoded_key.match(/.{1,2}/g)!.map((byte) => parseInt(byte, 16))
)
if (length > 0) {
key_bytes[15] = length
}
let formatted_serial_user = formatted_serial
if (ont_user) {
formatted_serial_user += `-${ont_user}`
}
let hmac = CryptoJS.HmacMD5(
formatted_serial_user,
CryptoJS.lib.WordArray.create(key_bytes as any)
)
let pw_md5_hmac = hexToBytes(hmac.toString(CryptoJS.enc.Hex))
let output = Array(pw_md5_hmac.length)
for (let i = 0; i < pw_md5_hmac.length; i++) {
output[i] = hardcoded_seed[pw_md5_hmac[i] % 0x36]
}
if (length > 0) {
return output.slice(0, length).join('')
} else {
return output.join('')
}
}
function handleSubmit(event: Event) {
const form = event.target as HTMLFormElement
validated.value = true
if (!form.checkValidity()) {
event.preventDefault()
event.stopPropagation()
} else {
result.value = cigpassword_gpon(serial.value, props.username || '')
}
form.classList.add('was-validated')
}
</script>
<style scoped>
.mb-3 {
margin-bottom: 1rem;
}
</style>