summaryrefslogtreecommitdiff
blob: f27023354b541a06c5b7076192f3e5ea67958c5f (plain)
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
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
# -*-eselect-*-  vim: ft=eselect
# Copyright 2005-2019 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2 or later
# $

DESCRIPTION="Control which metaploit version is active"
MAINTAINER="zerochaos@pentoo.ch"

###WARNING: don't even think of using this insanity for a reference (but it works,mostly)
#base idea from kernel.eselect with --use-old from opencl.eselect
#all modified randomly until it worked, entropy is wonderful
###/WARNING


MSFPATH="/usr/lib/metasploit"

# find a list of metasploit symlink targets and sort them
find_targets() {
	local f
	for f in "${EROOT}${MSFPATH}"[[:digit:]]*; do
		[[ -d ${f} ]] && basename "${f}"
	done | LC_ALL=C sort
}

# remove the metasploit symlink
remove_symlink() {
	for i in $(qlist metasploit | grep $(canonicalise "${EROOT}${MSFPATH}")/msf)
	do
		if [ -L /usr/bin/$(echo ${i} | awk -F'/' '{print $5}') ]; then
			unlink /usr/bin/$(echo ${i} | awk -F'/' '{print $5}') || die -q "failed to unlink ${i}"
		fi
	done
	if [ -L ${EROOT}${MSFPATH} ]; then
		unlink "${EROOT}${MSFPATH}" || die -q "failed to unlink ${EROOT}${MSFPATH}"
	elif [ -e ${EROOT}${MSFPATH} ]; then
		die -q "${EROOT}${MSFPATH} exists but is not a symlink"
	fi
}

# set the metasploit symlink
set_symlink() {
	local target=$1

	if is_number "${target}"; then
		local targets=( $(find_targets) )
		target=${targets[target-1]}
	fi

	if [[ -z ${target} ]]; then
		die -q "Target \"$1\" doesn't appear to be valid!"
	elif [[ -d ${EROOT}/usr/lib/${target} ]]; then
		ln -s "${target}" "${EROOT}${MSFPATH}"
		for i in $(qlist metasploit | grep /usr/lib/${target}/msf)
		do
			ln -s /usr/bin/msfloader /usr/bin/$(echo ${i} | awk -F'/' '{print $5}')
		done
	#this elif looks like it is trying to support setting by slot only,
	#but that isn't supported by the rest of the script... fix or remove?
	elif [[ -d ${EROOT}${MSFPATH}${target} ]]; then
		ln -s "metasploit${target}" "${EROOT}${MSFPATH}"
		for i in $(qlist metasploit | grep /usr/lib/${target}/msf)
		do
			ln -s /usr/bin/msfloader /usr/bin/$(echo ${i} | awk -F'/' '{print $5}')
		done
	else
		die -q "Target \"$1\" doesn't appear to be valid!"
	fi
}

# wrapper to safely set the symlink
set_symlink_safe() {
	if [[ -L ${EROOT}${MSFPATH} ]]; then
		# existing symlink
		remove_symlink || die -q "Couldn't remove existing symlink"
		set_symlink "$1" || die -q "Couldn't set a new symlink"
		#um, why is there an env-update here?
		env-update
	elif [[ -e ${EROOT}${MSFPATH} ]]; then
		# we have something strange
		die -q "${EROOT}${MSFPATH} exists but is not a symlink"
	else
		set_symlink "$1" || die -q "Couldn't set a new symlink"
	fi
}

### show action ###

describe_show() {
	echo "Show the current metasploit symlink"
}

do_show() {
	write_list_start "Current metasploit symlink:"
	if [[ -L ${EROOT}${MSFPATH} ]]; then
		local metasploit=$(canonicalise "${EROOT}${MSFPATH}")
		write_kv_list_entry "${metasploit%/}" ""
	else
		write_kv_list_entry "(unset)" ""
	fi
}

### list action ###

describe_list() {
	echo "List available metasploit symlink targets"
}

do_list() {
	local i targets=( $(find_targets) )

	write_list_start "Available metasploit symlink targets:"
	for (( i = 0; i < ${#targets[@]}; i++ )); do
		[[ ${targets[i]} = \
			$(basename "$(canonicalise "${EROOT}${MSFPATH}")") ]] \
			&& targets[i]=$(highlight_marker "${targets[i]}")
	done
	write_numbered_list -m "(none found)" "${targets[@]}"
}

### set action ###

describe_set() {
	echo "Set a new metasploit symlink target"
}

describe_set_parameters() {
	echo "<target>"
}

describe_set_options() {
	echo "<target> : Target name or number (from 'list' action)"
	echo "--use-old : If an implementation is already set, use that one instead"
}

do_set() {
	local action="error"
	local current=$(basename "$(canonicalise "${EROOT}${MSFPATH}")")
	local available=( $(find_targets) )
	local new
	local opt

	while [[ ${#@} -gt 0 ]] ; do
		opt=$1
		shift
		case ${opt} in
			--use-old)
				if [[ -n "${current}" ]] && has "${current}" "${available[@]}"; then
					action="old-implementation"
				fi
			;;
			metasploit*)
				if [[ "${action}" != "old-implementation" ]] ; then
					action="set-implementation"
				fi

				if has ${opt} ${available[@]}; then
					new="${opt}"
				else
					echo "You need to emerge ${opt} before you try to eselect it"
				fi
			;;
			*)
				if [[ "${action}" != "old-implementation" ]] ; then
					action="set-implementation"
				fi

				if is_number ${opt} ; then
					#targets=( $(get_implementations) )
					new=${available[opt - 1]}
					if [[ -z ${new} ]] ; then
						die -q "Unrecognized option: ${opt}"
					fi
				else
					die -q "Unrecognized option: ${opt}"
				fi
			;;
		esac
	done

	case ${action} in
		old-implementation)
			set_symlink_safe ${current}
			return $?
		;;
		set-implementation)
			if [[ -n ${new} ]] ; then
				set_symlink_safe ${new}
				return $?
			else
				die -q "Please specify an implementation to set"
			fi
		;;
		*)
			die -q "Invalid usage of set action."
		;;
	esac
}