I'm sorry for the length of this, if we should keep this off the list, please respond in private.
Simon Josefsson jas@extundo.com writes:
Would you start with the server or the client side? On the server, you need to inherit the userauth class in server_userauth.h, with some guidance from the class userauth_publickey in server_publickey.c. I think that should be reasonably straight forward.
Good. Clients are often easier to debug though, but I'll follow this pointer first.
It was rather straightforward, and I now have interop between lsh in server mode against OpenSSH (with the GSSAPI patches) in client mode. But. Once the authentication finished, lsh more or less crashes. I'm fairly certain this is because I don't understand the OOP stuff, and only have a few hours of experience with lsh in general. Here is output from lshd --debug ran under gdb, and the source code for the new server_gssapi.c. Any ideas? I suspect the error is in how do_handle_gssapi_finish() call COMMAND_RETURN(), or possibly how the gssapi_finish_handler class is defined OOP-wise.
Thanks, Simon
... lshd: write_buffer: do_write length = 48 lshd: write_buffer: do_write closure->length = 48 lshd: DEBUG: Received USERAUTH_REQUEST ***** lshd: handle_connection: Received packet of type 50 (USERAUTH_REQUEST) lshd: DEBUG: Sent USERAUTH_FAILURE lshd: (size 31 = 0x1f) 00000000: 330000001970617373776f72642c7075 3....password,pu 00000010: 626c69636b65792c67737361706900 blickey,gssapi.
lshd: write_buffer: do_write length = 56 lshd: write_buffer: do_write closure->length = 56 lshd: DEBUG: Received USERAUTH_REQUEST ***** lshd: handle_connection: Received packet of type 50 (USERAUTH_REQUEST) hepp 1 lshd: DEBUG: Sent USERAUTH_PK_OK|USERAUTH_PASSWD_CHANGEREQ|USERAUTH_GSSAPI_RESPONSE lshd: (size 16 = 0x10) 00000000: 3c0000000b06092a864886f712010202 <......*.H......
lshd: write_buffer: do_write length = 48 lshd: write_buffer: do_write closure->length = 48 lshd: DEBUG: Received USERAUTH_GSSAPI_TOKEN lshd: (size 1158 = 0x486) 00000000: 3d000004816082047d06092a864886f7 =....`..}..*.H.. 00000010: 1201020201006e82046c30820468a003 ......n..l0..h.. 00000020: 020105a10302010ea207030500200000 ............. .. 00000030: 00a38201286182012430820120a00302 ....(a..$0.. ... 00000040: 0105a10f1b0d4a4f53454653534f4e2e ......JOSEFSSON. 00000050: 4f5247a2263024a003020101a11d301b ORG.&0$.......0. 00000060: 1b04686f73741b136c617474652e6a6f ..host..latte.jo 00000070: 73656673736f6e2e6f7267a381df3081 sefsson.org...0. 00000080: dca003020110a103020103a281cf0481 ................ 00000090: ccf1fed3d9d3aa79c54b7396eaca1259 .......y.Ks....Y 000000a0: 9a58eec0e7682e2a342abdb41eb9486b .X...h.*4*....Hk 000000b0: 0f68fd3489bef45208ef1d140d344ca8 .h.4...R.....4L. 000000c0: f79b388b14e2fe4df259af16b1488921 ..8....M.Y...H.! 000000d0: c344920f1801d09f05782e275acb80a6 .D.......x.'Z... 000000e0: 70914a5bab2892c3b3fc6e8173114d31 p.J[.(....n.s.M1 000000f0: ae944e5e4ec861607152861794540aa5 ..N^N.a`qR...T.. 00000100: f5e092a1d08c28f15fba3ca8e35f18ec ......(._.<.._.. 00000110: d8bdaed7e53fb87a622b3ad8be1a6eff .....?.zb+:...n. 00000120: 41b86c0902d16cd47b130e7d1654e528 A.l...l.{..}.T.( 00000130: 4a43f9bc13849ba5234b457993e493ef JC......#KEy.... 00000140: a53d01fb936e1c373dfeb36b665fa00a .=...n.7=..kf_.. 00000150: d321688ee6bf0b89549f7d8cc3a48203 .!h.....T.}..... 00000160: 2530820321a003020110a28203180482 %0..!........... 00000170: 03142495fcd56ee48a8d3fecace801e8 ..$...n...?..... 00000180: a32c9f8ad73946ae6417e71aa8b801d0 .,...9F.d....... 00000190: 60e5a14e04c9ab9d49c4f368e65e303e `..N....I..h.^0> 000001a0: 23373693a708517c49ad393e9fb60549 #76...Q|I.9>...I 000001b0: 95a95dd066462cb6a033eb0ac70b136c ..].fF,..3.....l 000001c0: c20a3f7289907840f73d89c573f034ef ..?r..x@.=..s.4. 000001d0: 94e15559888626e6edc80bf1e04d8c58 ..UY..&......M.X 000001e0: ae101686e021e4341f9b857219450fc0 .....!.4...r.E.. 000001f0: f0f047b8bc457ba0d74a9004bac72da4 ..G..E{..J....-. 00000200: e45c81b479c42930f91ffa971975fd14 ...y.)0.....u.. 00000210: 6fb621de5fd369931a54cd1ff51b49c4 o.!._.i..T....I. 00000220: f37f190ce6afdc1f5f60ba227c40e674 ........_`."|@.t 00000230: db918f64bce55752a015a2eafed5b6a9 ...d..WR........ 00000240: f4124f68f31e0d46b04c9a435f118d3c ..Oh...F.L.C_..< 00000250: 2478e8e0618696e77529ddb7d340fd97 $x..a...u)...@.. 00000260: 5c84ba4860cfeebfafd12d4d83eb6c03 ..H`.....-M..l. 00000270: 68d66cec779a9771c69b7ee153929dfb h.l.w..q..~.S... 00000280: a80237d06ebba5bded29e07c89439616 ..7.n....).|.C.. 00000290: 2f575b8954eddff5720dff1ea1f8622d /W[.T...r.....b- 000002a0: d8794f1b8a91a8a265a7efc6df990469 .yO.....e......i 000002b0: 02df1e520e834352f0a157a7d0e60854 ...R..CR..W....T 000002c0: aa2cc821540188dddc347c1e199513c8 .,.!T....4|..... 000002d0: 0cd89477f4194b2a45467d9a07070e9a ...w..K*EF}..... 000002e0: 681dd699202f6fde0fba4417dc0e759e h... /o...D...u. 000002f0: 18e2ba96bc7541ea427ea37c96b3fb93 .....uA.B~.|.... 00000300: d95bb79d8655da32a489de26d14fb0c6 .[...U.2...&.O.. 00000310: 10dbf5cd9085e0151051aec23dfbf39b .........Q..=... 00000320: 168b2836fca4c2c7d22a48d6276087b8 ..(6.....*H.'`.. 00000330: 89b9a192b93b381b2cf415cd117a1fa1 .....;8.,....z.. 00000340: f8f5f288289bd8a8718b4c05e7092d26 ....(...q.L...-& 00000350: 2f8613a9763464b9ed8264c3bfcd2ca9 /...v4d...d...,. 00000360: 0926ea97c7289693fce7543eb716ec72 .&...(....T>...r 00000370: 3d25aaed8b5fea53856cfe31e18746a7 =%..._.S.l.1..F. 00000380: f343dea2a6b9ae5a1f21701b51b6decc .C.....Z.!p.Q... 00000390: 06641b1cb1b489572896226a620a9b5b .d.....W(."jb..[ 000003a0: e73272e4a302b693b3cbb37578d08bb9 .2r........ux... 000003b0: ec112aff82384f28966334d3ed6c1534 ..*..8O(.c4..l.4 000003c0: cdb85f01246d55178b54ccb11c43db06 .._.$mU..T...C.. 000003d0: 431fb3aa71da6726daf9d52162c4ceba C...q.g&...!b... 000003e0: 4366685ae0d625453f6bfb39abdb511d CfhZ..%E?k.9..Q. 000003f0: 2e23a6cee059cbcd7053dc33265c3f67 .#...Y..pS.3&?g 00000400: f20fe142156dc48945796c4bf1984be7 ...B.m..EylK..K. 00000410: 349ec5f7ecefb0adfce2f5cb748e7389 4...........t.s. 00000420: 8decad916af1f0249a5b030f3f783753 ....j..$.[..?x7S 00000430: 1a9328b317d5efbadd55ac492e863671 ..(......U.I..6q 00000440: e20b4a9f27e3ab793d86a1640a7049c8 ..J.'..y=..d.pI. 00000450: 435e92958e37ba301893e90072f9427b C^...7.0....r.B{ 00000460: 7ebf24bffc43217014fc840613a29e26 ~.$..C!p.......& 00000470: 1861bf5b06e1cb1e4107a479e84ca871 .a.[....A..y.L.q 00000480: f29fd62a5223 ...*R#
lshd: handle_connection: Received packet of type 61 (USERAUTH_GSSAPI_TOKEN) Error in re-setting breakpoint 1: Function "do_gssapi_done" not defined. Error in re-setting breakpoint 1: Function "do_gssapi_done" not defined. Error in re-setting breakpoint 1: Function "do_gssapi_done" not defined. lshd: DEBUG: Sent USERAUTH_GSSAPI_TOKEN lshd: (size 112 = 0x70) 00000000: 3d0000006b606906092a864886f71201 =...k`i..*.H.... 00000010: 020202006f5a3058a003020105a10302 ....oZ0X........ 00000020: 010fa24c304aa003020110a103020100 ...L0J.......... 00000030: a23e043c83cd60c58db638304549d2e6 .>.<..`...80EI.. 00000040: f3d20db3274657101987f9e8197dfeb8 ....'FW......}.. 00000050: 55987868d3695e737a1e77d2f05360e2 U.xh.i^sz.w..S`. 00000060: 71fea05d534500346b3f76383b2fc2a4 q..]SE.4k?v8;/..
lshd: write_buffer: do_write length = 144 lshd: write_buffer: do_write closure->length = 144 lshd: DEBUG: Received USERAUTH_GSSAPI_EXCHANGE_COMPLETE lshd: (size 1 = 0x1) 00000000: 3f ?
lshd: handle_connection: Received packet of type 63 (USERAUTH_GSSAPI_EXCHANGE_COMPLETE) ok lshd: connection.c:306: do_exc_connection_handler: Assertion `self->connection->paused' failed.
Program received signal SIGABRT, Aborted. 0x400cba41 in kill () from /lib/libc.so.6 (gdb) bt full #0 0x400cba41 in kill () from /lib/libc.so.6 No symbol table info available. #1 0x400cb862 in raise () from /lib/libc.so.6 No symbol table info available. #2 0x400cc976 in abort () from /lib/libc.so.6 No symbol table info available. #3 0x400c5ae9 in __assert_fail () from /lib/libc.so.6 No symbol table info available. #4 0x0805112e in do_exc_connection_handler (s=0x809d898, e=0xbfffad80) at connection.c:312 No locals. #5 0x080516be in connection_unlock (self=0x0) at connection.c:562 unpause = {super = {next = 0x0, isa = 0x0, alloc_method = 1 '\001', marked = 0 '\0', dead = 0 '\0'}, type = 1048580, msg = 0x807d8bd "unlocking connection."} #6 0x0805e082 in do_userauth_continuation (s=0x80b03e0, a=0x401b1f60) at server_userauth.c:145 i = 0 #7 0x0805c642 in do_handle_gssapi_finish (s=0x80bc288, connection=0x809ec68, packet=0x80bc508) at server_gssapi.c:97 self = (struct gssapi_finish_handler *) 0x80bc288 #8 0x08050cec in connection_handle_packet (closure=0x809ec68, packet=0x80bc508) at connection.c:155 msg = 63 '?' #9 0x080522fb in do_debug (w=0x809cfb0, packet=0x80bc508) at debug.c:66 No locals. #10 0x08065ee3 in do_packet_inflate (closure=0x809d008, packet=0x401b1f60) at compress.c:84 No locals. #11 0x08064368 in do_unpad (w=0x809d710, packet=0x80bd080) at unpad.c:97 padding_length = 96 '`' payload_length = 1075519328 new = (struct lsh_string *) 0x80bc508 #12 0x0805a674 in do_read_packet (h=0x809f29c, available=3221204656, data=0xbfffaf00 "�\020\204�\217_!\210�\003��\004�\210\213\005��\213\003'K�|�qOQ6�6.U\217K�\232\f�\v\+s<���:U3\001g\a�1z¨J\030֬%�\020%R\202�\006�\221\022dݡ9�F�\030-R\0236�\027�I����lK~vYh\200\005i\221#KXk�!hw�\225vB\177\203=/~�\036:\236w�\005�\035|0\215u.7�\223���+\201\004\aE(�d"0]\201�\202\224=�<�"�F\022\035b�N^uͧ���m�i4���2\027\204.��`ܩ\202D�c\201���"...) at read_packet.c:355 packet = (struct lsh_string *) 0x401b1f60 closure = (struct read_packet *) 0x80af4b0 total = 32 #13 0x08055718 in do_buffered_read (s=0x809f288, fd=0x809eb48) at io.c:498 buffer = ( uint8_t *) 0xbfffaef0 "���;0�\035\213>l3\024\215+�\231�\020\204�\217_!\210�\003��\004�\210\213\005��\213\003'K�|�qOQ6�6.U\217K�\232\f�\v\+s<���:U3\001g\a�1z¨J\030֬%�\020%R\202�\006�\221\022dݡ9�F�\030-R\0236�\027�I����lK~vYh\200\005i\221#KXk�!hw�\225vB\177\203=/~�\036:\236w�\005�\035|0\215u.7�\223���+\201\004\aE(�d"0]\201�\202\224=�<�"�F\022\035b�N^uͧ���m�i4���2\027"... res = 0 #14 0x08054f5b in lsh_oop_fd_read_callback (s=0x8092788, fileno=0, event=OOP_READ, data=0x809eb48) at io.c:140 No locals. #15 0x4006e0a9 in oop_sys_run () from /usr/lib/liboop.so.3 No symbol table info available. #16 0x08055551 in io_run () at io.c:337 res = (void *) 0x0 #17 0x0804be6a in main (argc=4, argv=0xbffff1b4) at lshd.c:1170 options = (struct lshd_options *) 0x809c928 resources = (struct resource_list *) 0x8092548 keys = (struct alist *) 0x8092568 fds = (struct resource *) 0x809e980 r = {rlim_cur = 4294967295, rlim_max = 4294967295} (gdb)
/* server_gssapi.c * * GSSAPI authentication method */
/* lsh, an implementation of the ssh protocol * * Copyright (C) 2003 Simon Josefsson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#if HAVE_CONFIG_H #include "config.h" #endif
#include "charset.h" #include "format.h" #include "parse.h" #include "ssh.h" #include "server_userauth.h" #include "werror.h" #include "xalloc.h"
#include "server_gssapi.c.x"
#if WITH_GSS
#include <gss.h>
static struct lsh_string * format_userauth_gssapi_response(uint32_t len, uint8_t *oid) { return ssh_format("%c%s", SSH_MSG_USERAUTH_GSSAPI_RESPONSE, len, oid); }
static void display_status_1 (char *m, OM_uint32 code, int type) { OM_uint32 maj_stat, min_stat; gss_buffer_desc msg; OM_uint32 msg_ctx;
msg_ctx = 0; do { maj_stat = gss_display_status (&min_stat, code, type, GSS_C_NULL_OID, &msg_ctx, &msg); printf("GSS-API error %s: %s\n", m, (char *) msg.value); gss_release_buffer (&min_stat, &msg); } while (msg_ctx); }
static void display_status (char *msg, OM_uint32 maj_stat, OM_uint32 min_stat) { display_status_1 (msg, maj_stat, GSS_C_GSS_CODE); display_status_1 (msg, min_stat, GSS_C_MECH_CODE); }
struct lsh_user *user; struct command_continuation *cont;
/* GABA: (class (name gssapi_finish_handler) (super packet_handler) (vars (gssapi object gssapi_server_instance))) */
static void do_handle_gssapi_finish(struct packet_handler *s, struct ssh_connection *connection, struct lsh_string *packet) { CAST(gssapi_finish_handler, self, s); puts("ok"); /* Remember that a user was authenticated. */ self->gssapi->user = USER_LOOKUP(self->gssapi->db, self->gssapi->username, 1); connection->user = self->gssapi->user; COMMAND_RETURN(self->gssapi->cont, self->gssapi->user); }
static struct packet_handler * make_gssapi_finish_handler(struct gssapi_server_instance *gssapi) { NEW(gssapi_finish_handler, self); self->super.handler = do_handle_gssapi_finish; self->gssapi = gssapi;
return &self->super; }
/* GABA: (class (name gssapi_token_handler) (super packet_handler) (vars (gssapi object gssapi_server_instance))) */
static void do_handle_gssapi_token(struct packet_handler *s, struct ssh_connection *connection, struct lsh_string *packet) { CAST(gssapi_token_handler, self, s); OM_uint32 maj_stat; OM_uint32 min_stat; OM_uint32 retflags; gss_ctx_id_t ctx = GSS_C_NO_CONTEXT; gss_cred_id_t cred = GSS_C_NO_CREDENTIAL; gss_buffer_desc inbuf, outbuf; gss_name_t client;
maj_stat = gss_acquire_cred (&min_stat, GSS_C_NO_NAME, 0, GSS_C_NULL_OID_SET, GSS_C_ACCEPT, &cred, NULL, NULL); if (GSS_ERROR(maj_stat)) { display_status("acquire_cred", maj_stat, min_stat); /* XXX send SSH_MSG_USERAUTH_GSSAPI_ERROR */ PROTOCOL_ERROR(connection->e, "GSSAPI acquire_cred failed."); }
inbuf.value = packet->data + 1 + 4; inbuf.length = packet->length - 1 - 4; maj_stat = gss_accept_sec_context (&min_stat, &ctx, cred, &inbuf, GSS_C_NO_CHANNEL_BINDINGS, &client, GSS_C_NO_OID, &outbuf, &retflags, NULL, NULL); if (maj_stat != GSS_S_COMPLETE && maj_stat != GSS_S_CONTINUE_NEEDED) { display_status("accept_sec_context", maj_stat, min_stat); /* XXX send SSH_MSG_USERAUTH_GSSAPI_ERROR */ PROTOCOL_ERROR(connection->e, "GSSAPI accept_sec_context failed."); }
if (maj_stat == GSS_S_COMPLETE) { connection->dispatch[SSH_MSG_USERAUTH_GSSAPI_TOKEN] = &connection_unimplemented_handler; connection->dispatch[SSH_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE] = make_gssapi_finish_handler(self->gssapi); C_WRITE(connection, ssh_format("%c%s", SSH_MSG_USERAUTH_GSSAPI_TOKEN, outbuf.length, outbuf.value)); return; } }
static struct packet_handler * make_gssapi_token_handler(struct gssapi_server_instance *gssapi) { NEW(gssapi_token_handler, self); self->super.handler = do_handle_gssapi_token; self->gssapi = gssapi;
return &self->super; }
/* GABA: (class (name userauth_gssapi) (super userauth) (vars (db object user_db))) */
/* GABA: (class (name gssapi_server_instance) (super userauth_gssapi) (vars (cont object command_continuation) (db object user_db) (user object lsh_user) (username object lsh_string))) */
static void do_authenticate(struct userauth *s, struct ssh_connection *connection UNUSED, struct lsh_string *username, uint32_t service UNUSED, struct simple_buffer *args, struct command_continuation *c, struct exception_handler *e) { CAST(userauth_gssapi, self, s);
NEW(gssapi_server_instance, gssapi);
int number_of_mechanisms;
username = utf8_to_local(username, 1, 1); if (!username) { PROTOCOL_ERROR(e, "Invalid utf8 in username."); return; } gssapi->username = username; gssapi->db = self->db; gssapi->cont = c;
if (parse_uint32(args, &number_of_mechanisms)) { int i; uint32_t len; uint8_t *oid;
printf("hepp %d\n", number_of_mechanisms);
for (i = 0; i < number_of_mechanisms; i++) if (!parse_string(args, &len, &oid)) goto fail;
connection->dispatch[SSH_MSG_USERAUTH_GSSAPI_TOKEN] = make_gssapi_token_handler (gssapi); EXCEPTION_RAISE(e, make_userauth_special_exception (format_userauth_gssapi_response(len, oid), NULL)); return; } fail: /* Request was invalid */ lsh_string_free(username);
PROTOCOL_ERROR(e, "Invalid gssapi USERAUTH message."); }
struct userauth * make_userauth_gssapi(struct user_db *db) { NEW(userauth_gssapi, self); self->super.authenticate = do_authenticate; self->db = db;
return &self->super; }
#endif /* WITH_GSS */