#include #include #include #include #include #include #include #include /* We just make these up, right? */ unsigned char ssh_uuid_nr[16] = { 0xa2, 0x8f, 0x80, 0x18, 0x92, 0x8a, 0x4b, 0x16, 0xa2, 0x2c, 0x0c, 0x4d, 0x93, 0xec, 0x36, 0xf1 }; static sdp_session_t *sdp_sess; static sdp_list_t *root_list, *l2cap_list, *rfcomm_list, *ssh_list, *proto_list, *access_proto_list, *profile_list, *svc_class_list; static sdp_data_t *chan; int register_sdp_record(uint8_t channel) { sdp_record_t rec; uuid_t root_uuid, l2cap_uuid, rfcomm_uuid, ssh_uuid; sdp_profile_desc_t profile_desc; memset(&rec, 0, sizeof(rec)); rec.handle = 0xffffffff; sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); root_list = sdp_list_append(0, &root_uuid); sdp_set_browse_groups(&rec, root_list); sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID); l2cap_list = sdp_list_append(0, &l2cap_uuid); proto_list = sdp_list_append(0, l2cap_list); sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID); chan = sdp_data_alloc(SDP_UINT8, &channel); rfcomm_list = sdp_list_append(0, &rfcomm_uuid); sdp_list_append(rfcomm_list, chan); sdp_list_append(proto_list, rfcomm_list); access_proto_list = sdp_list_append(0, proto_list); sdp_set_access_protos(&rec, access_proto_list); sdp_uuid128_create(&ssh_uuid, ssh_uuid_nr); ssh_list = sdp_list_append(0, &ssh_uuid); svc_class_list = sdp_list_append(0, &ssh_uuid); sdp_set_service_classes(&rec, svc_class_list); profile_desc.uuid = ssh_uuid; profile_desc.version = 0x100; profile_list = sdp_list_append(0, &profile_desc); sdp_set_profile_descs(&rec, profile_list); sdp_set_service_id(&rec, ssh_uuid); sdp_set_info_attr(&rec, "Secure Shell", NULL, NULL); sdp_sess = sdp_connect(BDADDR_ANY, BDADDR_LOCAL, 0); if (!sdp_sess) { perror("sdp_connect"); exit(1); } sdp_record_register(sdp_sess, &rec, 0); } void deregister_sdp_record(void) { sdp_data_free(chan); sdp_list_free(ssh_list, 0); sdp_list_free(rfcomm_list, 0); sdp_list_free(l2cap_list, 0); sdp_list_free(root_list, 0); sdp_list_free(proto_list, 0); sdp_list_free(access_proto_list, 0); sdp_list_free(svc_class_list, 0); sdp_list_free(profile_list, 0); sdp_close(sdp_sess); } int main(void) { int fd, lfd = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM); struct sockaddr_rc addr; socklen_t len = sizeof(addr); if (lfd < 0) { perror("socket"); exit(1); } memset(&addr, 0, sizeof(addr)); addr.rc_family = AF_BLUETOOTH; if (bind(lfd, (void *)&addr, sizeof(addr)) < 0) { perror("bind"); exit(1); } if (listen(lfd, 1) < 0) { perror("listen"); exit(1); } getsockname(lfd, (void *)&addr, &len); printf("Listening on channel %d\n", addr.rc_channel); register_sdp_record(addr.rc_channel); while ((fd = accept(lfd, (void *)&addr, &len)) >= 0) { printf("Got connection\n"); if (fork()) { close(fd); continue; } close(lfd); dup2(fd, 0); dup2(fd, 1); execl("/root/sshd", "/usr/sbin/sshd", "-i", "-f", "/etc/ssh/sshd_config", "-h", "/etc/ssh/ssh_host_dsa_key", NULL); perror("exec"); } deregister_sdp_record(); }