From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 12961 invoked by alias); 9 Apr 2010 22:27:58 -0000 Received: (qmail 12945 invoked by uid 22791); 9 Apr 2010 22:27:57 -0000 X-SWARE-Spam-Status: No, hits=-1.5 required=5.0 tests=BAYES_00,SARE_WEOFFER,TW_BJ,TW_CP,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mail.codesourcery.com (HELO mail.codesourcery.com) (38.113.113.100) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 09 Apr 2010 22:27:52 +0000 Received: (qmail 3619 invoked from network); 9 Apr 2010 22:27:51 -0000 Received: from unknown (HELO macbook-2.local) (stan@127.0.0.2) by mail.codesourcery.com with ESMTPA; 9 Apr 2010 22:27:51 -0000 Message-ID: <4BBFA9E1.1020609@codesourcery.com> Date: Fri, 09 Apr 2010 22:27:00 -0000 From: Stan Shebs User-Agent: Thunderbird 2.0.0.24 (Macintosh/20100228) MIME-Version: 1.0 To: gdb-patches@sourceware.org Subject: [RFC] Add login to remote protocol Content-Type: multipart/mixed; boundary="------------010908010800090501010904" Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2010-04/txt/msg00289.txt.bz2 This is a multi-part message in MIME format. --------------010908010800090501010904 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Content-length: 1595 This patch is somewhat more specialized than the tracepoint stuff, but may be of wider interest, so we offer it for your consideration. It adds a login capability to the remote protocol; the user sets a username and password in GDB, then upon connection to a target that requires them, GDB supplies the two. It is completely up to the target what do with them, for instance it could simply close the connection in response to a bad login. The design is simple, and not especially secure, as the password is sent in the clear - it's mostly appropriate for direct connections or secured intranets. We don't do anything to conceal the password from the console, but one could add a non-echoing reader, and write a password show that kept it concealed. The patch below is actually somewhat out of date, but it should be sufficient for discussion, and I'll update it into a real patch if the consensus is in favor of including this capability in GDB. Stan 2009-02-04 Stan Shebs Remote login support. gdb/ * remote.c (remote_username, remote_password): New globals. (struct remote_state): New field must_auth. (PACKET_qAuth): New enum. (remote_start_remote): Send qAuth if required. (remote_query_auth): New. (remote_must_auth_feature): New. (remote_protocol_features): Add MustAuth. (_initialize_remote): Add qAuth packet, set commands. gdb/doc/ * gdb.texinfo (Remote Configuration): Document set remote username and password. (General Query Packets): Document qAuth packet and MustAuth feature. --------------010908010800090501010904 Content-Type: text/plain; x-mac-type="0"; x-mac-creator="0"; name="auth-patch-1" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="auth-patch-1" Content-length: 7604 Index: gdb/doc/gdb.texinfo =================================================================== *** gdb/doc/gdb.texinfo (revision 235760) --- gdb/doc/gdb.texinfo (revision 235761) *************** extended-remote}. This should be set to *** 14180,14185 **** --- 14180,14195 ---- target system. If it is not set, the target will use a default filename (e.g.@: the last program run). + @item set remote username @var{username} + @itemx show remote username + Set the username to be sent to targets that require a login. The + username is an arbitary string. + + @item set remote password @var{password} + @itemx show remote password + Set the password to be sent to targets that require a login. The + password is an arbitary string. At present it is stored as cleartext. + @kindex set tcp @kindex show tcp @item set tcp auto-retry on *************** Here are the currently defined query and *** 26157,26162 **** --- 26167,26184 ---- @table @samp + @item qAuth:@var{username},@var{password} + @cindex @samp{qAuth} packet + Request permission to debug the target. The @var{username} and + @var{password} are the values from @code{set remote username} and + @code{set remote password}, both encoded as hex strings. If the + target accepts the username and password, then it replies with + @samp{OK}; otherwise it replies with an error and may disconnect on + its own. If the target requires a login (@samp{MustAuth} feature), + then if this packet is not supplied soon after connection, then the + target may choose to return errors to all subsequent packets and/or + disconnect. + @item qC @cindex current thread, remote request @cindex @samp{qC} packet *************** These are the currently defined stub fea *** 26599,26604 **** --- 26621,26631 ---- @tab @samp{-} @tab No + @item @samp{MustAuth} + @tab No + @tab @samp{-} + @tab No + @end multitable These are the currently defined stub features, in more detail: *************** indicated it supports them in its @samp{ *** 26668,26673 **** --- 26695,26707 ---- The remote stub understands the @samp{qXfer:osdata:read} packet ((@pxref{qXfer osdata read}). + @item MustAuth + @value{GDBN} must send an authorization packet @samp{qAuth} and the + username/password pair must be accepted, otherwise the target will + return an error and refuse to continue with the session. (It is up to + the target whether it actually disconnects, or simply does not respond + further.) + @end table @item qSymbol:: Index: gdb/remote.c =================================================================== *** gdb/remote.c (revision 235760) --- gdb/remote.c (revision 235761) *************** static void show_remote_protocol_packet_ *** 213,218 **** --- 213,222 ---- static char *write_ptid (char *buf, const char *endbuf, ptid_t ptid); static ptid_t read_ptid (char *buf, char **obuf); + struct remote_state; + + static void remote_query_auth (struct remote_state *); + static void remote_query_supported (void); static void remote_check_symbols (struct objfile *objfile); *************** struct remote_state *** 305,310 **** --- 309,318 ---- /* True if the stub reports support for vCont;t. */ int support_vCont_t; + + /* True if the stub requires successful authorization before + completing the connection. */ + int must_auth; }; /* Returns true if the multi-process extensions are in effect. */ *************** static int remote_async_terminal_ours_p; *** 589,594 **** --- 597,608 ---- static char *remote_exec_file = ""; + /* A username/password pair for targets that want basic + authentication. */ + + static char *remote_username = ""; + static char *remote_password = ""; + /* User configurable variables for the number of characters in a memory read/write packet. MIN (rsa->remote_packet_size, *************** enum { *** 1001,1006 **** --- 1015,1021 ---- PACKET_vRun, PACKET_QStartNoAckMode, PACKET_vKill, + PACKET_qAuth, PACKET_MAX }; *************** remote_start_remote (struct ui_out *uiou *** 2525,2530 **** --- 2540,2549 ---- which later probes to skip. */ remote_query_supported (); + /* Before going any further, see if we have permission. */ + if (rs->must_auth) + remote_query_auth (rs); + /* Next, we possibly activate noack mode. If the QStartNoAckMode packet configuration is set to AUTO, *************** Some events may be lost, rendering furth *** 2844,2849 **** --- 2863,2889 ---- return serial_open (name); } + /* Ask the target whether the given username and password is acceptable. */ + + static void + remote_query_auth (struct remote_state *rs) + { + int len; + + strcpy (rs->buf, "qAuth:"); + len = strlen (rs->buf); + len += 2 * bin2hex ((gdb_byte *) remote_username, rs->buf + len, 0); + rs->buf[len++] = ';'; + len += 2 * bin2hex ((gdb_byte *) remote_password, rs->buf + len, 0); + rs->buf[len++] = '\0'; + + putpkt (rs->buf); + + getpkt (&rs->buf, &rs->buf_size, 0); + if (strcmp (rs->buf, "OK") != 0) + error ("Not authorized to connect\n"); + } + /* This type describes each known response to the qSupported packet. */ struct protocol_feature *************** remote_non_stop_feature (const struct pr *** 2943,2948 **** --- 2983,2996 ---- rs->non_stop_aware = (support == PACKET_ENABLE); } + static void + remote_must_auth_feature (const struct protocol_feature *feature, + enum packet_support support, const char *value) + { + struct remote_state *rs = get_remote_state (); + rs->must_auth = (support == PACKET_ENABLE); + } + static struct protocol_feature remote_protocol_features[] = { { "PacketSize", PACKET_DISABLE, remote_packet_size, -1 }, { "qXfer:auxv:read", PACKET_DISABLE, remote_supported_packet, *************** static struct protocol_feature remote_pr *** 2965,2970 **** --- 3013,3020 ---- PACKET_QStartNoAckMode }, { "multiprocess", PACKET_DISABLE, remote_multi_process_feature, -1 }, { "QNonStop", PACKET_DISABLE, remote_non_stop_feature, -1 }, + { "MustAuth", PACKET_DISABLE, remote_must_auth_feature, + PACKET_qAuth }, }; static void *************** Show the maximum size of the address (in *** 9118,9123 **** --- 9168,9176 ---- add_packet_config_cmd (&remote_protocol_packets[PACKET_vKill], "vKill", "kill", 0); + add_packet_config_cmd (&remote_protocol_packets[PACKET_qAuth], + "qAuth", "auth", 0); + /* Keep the old ``set remote Z-packet ...'' working. Each individual Z sub-packet has its own set and show commands, but users may have sets to this variable in their .gdbinit files (or in their *************** Set the remote pathname for \"run\""), _ *** 9157,9162 **** --- 9210,9229 ---- Show the remote pathname for \"run\""), NULL, NULL, NULL, &remote_set_cmdlist, &remote_show_cmdlist); + remote_username = xstrdup (""); + add_setshow_string_noescape_cmd ("username", class_files, + &remote_username, _("\ + Set the remote username"), _("\ + Show the remote username"), NULL, NULL, NULL, + &remote_set_cmdlist, &remote_show_cmdlist); + + remote_password = xstrdup (""); + add_setshow_string_noescape_cmd ("password", class_files, + &remote_password, _("\ + Set the remote password"), _("\ + Show the remote password"), NULL, NULL, NULL, + &remote_set_cmdlist, &remote_show_cmdlist); + /* Eventually initialize fileio. See fileio.c */ initialize_remote_fileio (remote_set_cmdlist, remote_show_cmdlist); --------------010908010800090501010904--