summary refs log blame commit diff stats
path: root/widgets/exline.go
blob: f2c7249f12b43efd08defd84071e82b8e5e140fa (plain) (tree)
5685a17 ^
<
<HTML>
<HEAD>
<TITLE>Computer Hacking and Ethics</TITLE>
</HEAD>
<BODY>
<H1>Computer Hacking and Ethics</H1>
<CITE>Brian Harvey<BR>University of California, Berkeley</CITE>

<P>[A slightly different version of this paper was written for the
``Panel on Hacking'' held by the Association for Computing Machinery in
April, 1985.  Thanks to Batya Friedman, Donn Parker, and Carter Sanders for
their comments on early drafts.]

<BLOCKQUOTE>
<P>[Neal Patrick] said he and his friends, who named
themselves the ``414s'' after the Milwaukee area code, did not
intend to do any damage and did not realize they were doing
anything unethical or illegal.  In fact, when asked [at a
Congressional subcommittee hearing] at what point he questioned
the ethics of his actions, he answered, ``Once the FBI knocked
on the door.''

<P>-- "`Common Sense' Urged on Computer Break-Ins,"
26 Sept 83; Copyright 1983 New York Times News Service
</BLOCKQUOTE>


<P>It's no secret that a mature sense of ethics is something a person
develops over time.  Parents are supposed to exercise authority over their
children because the children are not expected to know how to make certain
decisions for themselves.  We have a juvenile court system separate from the
adult criminal court system because we believe that a young person is not
<EM>capable</EM> of criminal intent in the same sense that an adult is
capable of it.

<P>Within this century, the obvious idea that the ethical sense
of an adolescent isn't the same as that of an adult has become the
focus of scientific research.  Psychologists have entered a field
once left to philosophers: moral development.  The best-known attempt
to formalize this development is probably the six-stage theory of
Harvard psychologist Lawrence Kohlberg.  Here is his description of
Stage 3, the Interpersonal Concordance or ``Good Boy-Nice Girl'' Orientation:

<BLOCKQUOTE>
<P>Good behavior is that which pleases or helps
others and is approved by them.  There is much conformity
to stereotypical images of what is majority or ``natural'' behavior.
Behavior is frequently judged by intention--the judgment ``he
means well'' becomes important for the first time.  One earns
approval by being ``nice.'' [Kohlberg, p. 18]
</BLOCKQUOTE>

<P>Is Neal Patrick at this third stage of moral development?  He seems
to judge his own actions in terms of intention.  From the perspective
of the stage theory, we can see this as an improvement over ``Our mistake
was to get caught'' or ``What have those computer companies done for
me,'' responses that would be typical of the earlier stages.

<P>I don't mean to give too much weight to the specifics of the third stage.
It's not scientifically valid to assign Patrick to a developmental stage on
the basis of one quoted sentence.  Also, not every researcher accepts
Kohlberg's stages.  But the important point is that Patrick is
<EM>roughly</EM> at the stage of moral development appropriate to his age.  He is
not some new kind of monster spawned by computer technology; he's a kid with
all the strengths and weaknesses we expect from kids in other situations.

<P>Compare a bunch of adolescents breaking into a computer system
with another bunch of kids hot-wiring a car for a joyride.  The latter
would probably argue, with complete sincerity, that they were doing
no harm, because the owner of the car recovered his property afterward.
They didn't keep or sell it.  It's a ``naughty'' prank to borrow someone's
property in that way, but not really serious.

<P>These hypothetical car thieves would be wrong, of course, in
making that argument.  They might lack the sensitivity needed to give
weight to the victim's feelings of manipulation, of fear, of anger.
They may not understand how the experience of such a random attack
can leave a person feeling a profound loss of order and safety in
the world--the feeling that leads half our population to hail Bernhard
Goetz as a hero to be emulated.  Some adolescents don't have the empathy
to see beyond the issue of loss of property.  Some may show empathy
in certain situations but not in others.

<P>The point is that the computer raises no new issue, ethical or
pragmatic.  The password hacker who says ``we aren't hurting anything
by looking around'' is exactly analogous to the joyrider saying ``we
aren't stealing the car permanently.''

<P>(The two cases need not seem analogous to an adolescent.  There
may be many computer abusers who would never break into a car for
a joyride, but who don't understand that breaking into a computer
account raises the same ethical issues.  But the analogy still holds
for us as adults.)

<P>The professional car thief and the teenaged joyrider are both social
problems, but they're <EM>different</EM> problems.  To confuse the two--to
treat the teenager like a career criminal--would be a disastrously
self-fulfilling prophecy.

<P>In the context of computer systems, there is a similar dichotomy.  There are
some career criminals who steal by electronic means.  This small group poses
a large problem for society, but it's not a new one.  Thieves are thieves.
Just as banks use special armored cars, they must also develop special
armored computer systems.  But the rest of us don't use armored cars for
routine transportation, and we don't need armored computer systems for
routine communication either.  (Of course there is a large middle ground
between heavy security and no security at all.  My purpose here is not to
decide exactly what security measures are appropriate for any particular
computer system.  Instead, I just want to make it clear that, while in this
paper I'm not trying to address the problem of professional criminals, I'm
not trying to deny that there is such a problem either.)

<P>There is also a middle ground between the young person who happens to break
unimportant rules in the innocent exercise of intellectual curiosity and the
hardened criminal.  Consider the hypothetical case of a young man whose
girlfriend moves to Australia for a year, and so he builds himself a blue
box (a device used to place long distance telephone calls without paying for
them) and uses it to chat with her for an hour every other day.  This is not
intellectual curiosity, nor is it a deliberate, long-term choice of a life
of crime.  Instead, this hypothetical adolescent, probably normally honest,
has stepped over a line without really noticing it, because his mind is
focused on something else.  It would be inappropriate, I think, to pat him
on the head and tell him how clever he is, and equally inappropriate to
throw him in prison.  What we must do is call his attention to the
inconsistency between his activities and, most likely, his own moral
standards.

<H2>Two Models for Moral Direction</H2>

<P>What to do about it?  Saying that the problems of computer ethics
are like other ethical problems doesn't solve them.  Many approaches
are possible.  We are starting to hear among computer experts the
same debates we've heard for centuries among criminologists: prevention,
deterrence, retribution, cure?

<P>Among all the possible approaches, it may be instructive to consider
two strongly opposed ones: first, control of the technology, and second,
moral training.  As examples of these approaches, compare the registration
of automobiles with instruction in karate.

<P>Automobile registration is certainly a good idea in helping the
police control professional crime.  As thieves have learned to steal
cars for their parts, rather than to sell whole, the technology of
registration has had to grow more sophisticated: we now see serial
numbers on each major component, not just on the door frame.  But
registration doesn't help against joyriders.

<P>Other technological security measures can help.  Steering column
locks have made joyriding harder, but not impossible.  Many adolescents
are expert locksmiths, not because they're dishonest but because locks
and keys pose a technical challenge much like that of passwords in
a computer system.  Also, increased security has made the consequences
of juvenile car theft more serious, because the easiest way to defeat
a steering column lock is to destroy it by brute force.

<P>The example of karate instruction shows a very different approach
to the problem of adolescent moral limitations.  Instead of using
technology to limit the power of young people, this second approach
deliberately empowers them.  Skill in karate is a deadly weapon; to
give that weapon to a young person is an affirmation of trust rather
than suspicion.

<P>Why do karate classes for kids work?  Why don't they lead to
an epidemic of juvenile murders?  This paper can't present a definitive
answer.  But I want to suggest some possibilities and use them to draw
analogies for computer education.

<P>One probable reason is that every person responds to his or her
situation.  If I know you're trusting me with something important,
I'll try to live up to your trust.  If I sense that you consider me
untrustworthy, I may decide that I might as well live up to your low
expectations.

<P>Another vital reason, though, is that the technical instruction
in karate techniques is part of a larger initiation into a certain
culture and its rules.  Karate schools don't begin by telling novices,
``Here's how to kill someone.'' They begin with simple, less dangerous
techniques; the criteria for advancement include <EM>control</EM> and
self-discipline as well as knowledge of particular moves.  Instructors
emphasize that karate is an art that should not be abused.  Students learn
to demonstrate punches and kicks without injury by stopping just short of
contact with the opponent's body.

<H2>Empowerment in Computer Education</H2>

<P>How can we <EM>teach</EM> young computer enthusiasts to be responsible
members of the electronic community, without defining them as criminals?
The analogy of karate instruction suggests that the answer is to combine
ethical training with real empowerment.  To turn this broad slogan
into a practical program requires several changes in our approach
to educational computing and to computing in general.

<BLOCKQUOTE>
<P>Growth, like any ongoing function, requires adequate
objects in the environment to meet the needs and capacities
of the growing child, boy, youth, and young man, until he
can better choose and make his own environment.  It is not
a ``psychological'' question of poor influences and bad attitudes,
but an objective question of real opportunities for worthwhile
experience....  Thwarted, or starved, in the important objects
proper to young capacities, the boys and young men naturally
find or invent deviant objects for themselves; this is the
beautiful shaping power of our human nature.  Their choices
and inventions are rarely charming, usually stupid, and often
disastrous; we cannot expect average kids to deviate with
genius. [Goodman, pp. 12-13]
</BLOCKQUOTE>

<P>Paul Goodman was discussing traditional juvenile delinquents, not
password hackers.  But the problem is fundamentally the same.  How
can we provide a worthwhile culture for young computer enthusiasts
to grow into?

<P><STRONG>1.  Serious adult models.</pre { line-height: 125%; }
td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
.highlight .hll { background-color: #ffffcc }
.highlight .c { color: #888888 } /* Comment */
.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.highlight .k { color: #008800; font-weight: bold } /* Keyword */
.highlight .ch { color: #888888 } /* Comment.Hashbang */
.highlight .cm { color: #888888 } /* Comment.Multiline */
.highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */
.highlight .cpf { color: #888888 } /* Comment.PreprocFile */
.highlight .c1 { color: #888888 } /* Comment.Single */
.highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */
.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */
.highlight .gr { color: #aa0000 } /* Generic.Error */
.highlight .gh { color: #333333 } /* Generic.Heading */
.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.highlight .go { color: #888888 } /* Generic.Output */
.highlight .gp { color: #555555 } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #666666 } /* Generic.Subheading */
.highlight .gt { color: #aa0000 } /* Generic.Traceback */
.highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */
.highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */
.highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */
.highlight .kp { color: #008800 } /* Keyword.Pseudo */
.highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */
.highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */
.highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */
.highlight .na { color: #336699 } /* Name.Attribute */
.highlight .nb { color: #003388 } /* Name.Builtin */
.highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */
.highlight .no { color: #003366; font-weight: bold } /* Name.Constant */
.highlight .nd { color: #555555 } /* Name.Decorator */
.highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */
.highlight .nl { color: #336699; font-style: italic } /* Name.Label */
.highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */
.highlight .py { color: #336699; font-weight: bold } /* Name.Property */
.highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */
.highlight .nv { color: #336699 } /* Name.Variable */
.highlight .ow { color: #008800 } /* Operator.Word */
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
.highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */
.highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */
.highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */
.highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */
.highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */
.highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */
.highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */
.highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */
.highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */
.highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */
.highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */
.highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */
.highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */
.highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */
.highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */
.highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */
.highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */
.highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */
.highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */
.highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */
.highlight .vc { color: #336699 } /* Name.Variable.Class */
.highlight .vg { color: #dd7700 } /* Name.Variable.Global */
.highlight .vi { color: #3333bb } /* Name.Variable.Instance */
.highlight .vm { color: #336699 } /* Name.Variable.Magic */
.highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
package widgets

import (
	"github.com/gdamore/tcell"

	"git.sr.ht/~sircmpwn/aerc/lib"
	"git.sr.ht/~sircmpwn/aerc/lib/ui"
)

type ExLine struct {
	ui.Invalidatable
	commit      func(cmd string)
	finish      func()
	tabcomplete func(cmd string) []string
	cmdHistory  lib.History
	input       *ui.TextInput
}

func NewExLine(cmd string, commit func(cmd string), finish func(),
	tabcomplete func(cmd string) []string,
	cmdHistory lib.History) *ExLine {

	input := ui.NewTextInput("").Prompt(":").TabComplete(tabcomplete).Set(cmd)
	exline := &ExLine{
		commit:      commit,
		finish:      finish,
		tabcomplete: tabcomplete,
		cmdHistory:  cmdHistory,
		input:       input,
	}
	input.OnInvalidate(func(d ui.Drawable) {
		exline.Invalidate()
	})
	return exline
}

func NewPrompt(prompt string, commit func(text string),
	tabcomplete func(cmd string) []string) *ExLine {

	input := ui.NewTextInput("").Prompt(prompt).TabComplete(tabcomplete)
	exline := &ExLine{
		commit:      commit,
		tabcomplete: tabcomplete,
		cmdHistory:  &nullHistory{input: input},
		input:       input,
	}
	input.OnInvalidate(func(d ui.Drawable) {
		exline.Invalidate()
	})
	return exline
}

func (ex *ExLine) Invalidate() {
	ex.DoInvalidate(ex)
}

func (ex *ExLine) Draw(ctx *ui.Context) {
	ex.input.Draw(ctx)
}

func (ex *ExLine) Focus(focus bool) {
	ex.input.Focus(focus)
}

func (ex *ExLine) Event(event tcell.Event) bool {
	switch event := event.(type) {
	case *tcell.EventKey:
		switch event.Key() {
		case tcell.KeyEnter, tcell.KeyCtrlJ:
			cmd := ex.input.String()
			ex.input.Focus(false)
			ex.commit(cmd)
			ex.finish()
		case tcell.KeyUp:
			ex.input.Set(ex.cmdHistory.Prev())
			ex.Invalidate()
		case tcell.KeyDown:
			ex.input.Set(ex.cmdHistory.Next())
			ex.Invalidate()
		case tcell.KeyEsc, tcell.KeyCtrlC:
			ex.input.Focus(false)
			ex.cmdHistory.Reset()
			ex.finish()
		default:
			return ex.input.Event(event)
		}
	}
	return true
}

type nullHistory struct {
	input *ui.TextInput
}

func (*nullHistory) Add(string) {}

func (h *nullHistory) Next() string {
	return h.input.String()
}

func (h *nullHistory) Prev() string {
	return h.input.String()
}

func (*nullHistory) Reset() {}