signed Antiphon (struct plc * plc, byte source [], byte target []) { struct channel * channel = (struct channel *)(plc->channel); struct message * message = (struct message *)(plc->message); #ifndef __GNUC__ #pragma pack (push,1) #endif struct __packed vs_fr_lbk_request { struct ethernet_std ethernet; struct qualcomm_std qualcomm; uint8_t DURATION; uint8_t RESERVED; uint16_t LENGTH; uint8_t PACKET [1038]; } * request = (struct vs_fr_lbk_request *) (message); #ifndef __GNUC__ #pragma pack (pop) #endif if (_allclr (plc->flags, PLC_SILENCE)) { char sourcename [ETHER_ADDR_LEN * 3]; char targetname [ETHER_ADDR_LEN * 3]; hexdecode (source, ETHER_ADDR_LEN, sourcename, sizeof (sourcename)); hexdecode (target, ETHER_ADDR_LEN, targetname, sizeof (targetname)); fprintf (stderr, "%s %s %s\n", channel->ifname, sourcename, targetname); } memset (message, 0, sizeof (* message)); EthernetHeader (&message->ethernet, source, channel->host, HOMEPLUG_MTYPE); QualcommHeader (&message->qualcomm, 0, (VS_FR_LBK | MMTYPE_REQ)); request->DURATION = plc->timer; request->LENGTH = HTOLE16 (sizeof (request->PACKET)); memset (request->PACKET, 0xA5, sizeof (request->PACKET)); EthernetHeader (request->PACKET, target, source, ETHERTYPE_IP); plc->packetsize = sizeof (* request); if (SendMME (plc) <= 0) { error (1, errno, CHANNEL_CANTSEND); } if (ReadMME (plc, 0, (VS_FR_LBK | MMTYPE_CNF)) <= 0) { error (1, errno, CHANNEL_CANTREAD); } sleep (plc->timer); return (0); }
static int sha512_monte_carlo_core ( const char *seed, const char *checks[100] ) { struct sha512_ctx_t sha; sha512_init(&sha); unsigned char md0[64],md1[64],md2[64]; int ret = hexdecode(md0,seed,64); if (ret) { youfail(); printf(" SHA-512 NIST Monte Carlo validation seed hex decode failure.\n"); return -1; } int i,j; memcpy(md1,md0,sizeof(md1)); memcpy(md2,md0,sizeof(md1)); for (j=0; j<100; j++) { for (i=3; i<1003; i++) { sha512_update(&sha,md0,sizeof(md0)); sha512_update(&sha,md1,sizeof(md1)); sha512_update(&sha,md2,sizeof(md2)); memcpy(md0,md1,sizeof(md1)); memcpy(md1,md2,sizeof(md1)); sha512_final(&sha,md2); } ret = hexdecode(md0,checks[j],64); if (ret) { youfail(); printf(" SHA-512 NIST Monte Carlo validation hex decode failure at iteration %d\n", j); return -1; } else if (memcmp(md0,md2,sizeof(md2))) { youfail(); printf(" SHA-512 NIST Monte Carlo validation failure at iteration %d\n", j); hexprint(" Expected", md0, 64); hexprint(" But got ", md2, 64); return j+1; } memcpy(md0,md2,sizeof(md1)); memcpy(md1,md2,sizeof(md1)); } return 0; }
char *create_shellcode(void){ char *content_length, *aux, *page, *ret = NULL; char buf[1024], sc[256]; size_t len, size, pos = 0; ssize_t n, i; if((content_length = getenv("CONTENT_LENGTH")) == NULL){ die("CONTENT_LENGTH not set\n"); } len = strtol(content_length, NULL ,10); size = len/4; page = mmap(0, size, PROT_EXEC|PROT_WRITE|PROT_READ, MAP_ANON|MAP_PRIVATE, -1, 0); if(page == MAP_FAILED){ die("mmap failed\n"); } while((n = read(STDIN_FILENO, buf, sizeof(buf))) > 0){ if(n%4) goto end; aux = sc; for(i=0; i<n; i+=4){ if(buf[i] != '\\') goto end; if(buf[i+1] != 'x') goto end; if(!isxdigit(buf[i+2]) || !isxdigit(buf[i+3])) goto end; *aux++ = (hexdecode(buf[i+2])*16)|hexdecode(buf[i+3]); } n = n/4; memcpy(page+pos, sc, n); pos += n; } ret = page; end: return ret; }
QString Kleo::gpgConfListDir( const char * which ) { if ( !which || !*which ) return QString(); const QString gpgConfPath = Kleo::gpgConfPath(); if ( gpgConfPath.isEmpty() ) return QString(); QProcess gpgConf; kDebug() << "gpgConfListDir: starting " << qPrintable( gpgConfPath ) << " --list-dirs"; gpgConf.start( gpgConfPath, QStringList() << QLatin1String( "--list-dirs" ) ); if ( !gpgConf.waitForFinished() ) { kDebug() << "gpgConfListDir(): failed to execute gpgconf: " << qPrintable( gpgConf.errorString() ); kDebug() << "output was:" << endl << gpgConf.readAllStandardError().constData(); return QString(); } const QList<QByteArray> lines = gpgConf.readAllStandardOutput().split( '\n' ); Q_FOREACH( const QByteArray & line, lines ) if ( line.startsWith( which ) && line[qstrlen(which)] == ':' ) { const int begin = qstrlen(which) + 1; int end = line.size(); while ( end && ( line[end-1] == '\n' || line[end-1] == '\r' ) ) --end; const QString result = QDir::fromNativeSeparators( QFile::decodeName( hexdecode( line.mid( begin, end - begin ) ) ) ); kDebug() << "gpgConfListDir: found " << qPrintable( result ) << " for '" << which << "'entry"; return result; } kDebug() << "gpgConfListDir(): didn't find '" << which << "'" << "entry in output:" << endl << gpgConf.readAllStandardError().constData(); return QString(); }
static void test_keccak_hmac(const size_t * chunks) { uint8_t inp_buff[1024]; uint8_t key_buff[1024]; uint8_t res_exp[32]; uint8_t res_comp[32]; size_t len_chunks = 0; for(; chunks && chunks[len_chunks] > 0; ++len_chunks); for (size_t i = 0; i < (sizeof(keccak_hmac_vectors) / sizeof(*keccak_hmac_vectors)); i++) { const size_t inp_len = strlen(keccak_hmac_vectors[i].inp)/2; const size_t key_len = strlen(keccak_hmac_vectors[i].key)/2; ASSERT_TRUE(hexdecode(keccak_hmac_vectors[i].inp, inp_len, inp_buff)); ASSERT_TRUE(hexdecode(keccak_hmac_vectors[i].key, key_len, key_buff)); ASSERT_TRUE(hexdecode(keccak_hmac_vectors[i].res, 32, res_exp)); if (len_chunks == 0) { hmac_keccak_hash(res_comp, key_buff, key_len, inp_buff, inp_len); } else { hmac_keccak_state S; hmac_keccak_init(&S, key_buff, key_len); size_t inp_passed = 0; size_t chunk_size = 0; while(inp_passed < inp_len){ const size_t to_pass = std::min(inp_len - inp_passed, chunks[chunk_size]); hmac_keccak_update(&S, inp_buff + inp_passed, to_pass); inp_passed += to_pass; chunk_size = (chunk_size + 1) % len_chunks; } hmac_keccak_finish(&S, res_comp); } ASSERT_EQ(memcmp(res_exp, res_comp, 32), 0); } }
int main(int argc, char **argv){ char *cmd; setreuid(geteuid(), geteuid()); if (argc == 2) { cmd = hexdecode(argv[1]); if (!strcmp(cmd, "hostname")){ /* Fake hostname as flag. */ puts("too-many-secrets.playtronics.int\n"); return 0; } return system(cmd); } return -1; }
int main(int argc, char const * argv[]) { byte memory[16]; char buffer[100]; while (* ++ argv) { memset (memory, 0, sizeof(memory)); numencode (memory, sizeof(memory), * argv, 10, '.'); hexdecode (memory, sizeof(memory), buffer, sizeof(buffer)); printf ("%s=[%s]\n", * argv, buffer); } return (0); }
void Display (struct plc * plc, char const *format, ...) { char address [ETHER_ADDR_LEN * 3]; struct channel * channel = (struct channel *)(plc->channel); struct message * message = (struct message *)(plc->message); hexdecode (message->ethernet.OSA, sizeof (message->ethernet.OSA), address, sizeof (address)); printf ("%s %s ", channel->ifname, address); if ((format) && (*format)) { va_list arglist; va_start (arglist, format); vprintf (format, arglist); va_end (arglist); } printf ("\n"); return; }
void Request (struct plc * plc, char const *format, ...) { if (_allclr (plc->flags, PLC_SILENCE)) { char address [ETHER_ADDR_LEN * 3]; struct channel * channel = (struct channel *)(plc->channel); hexdecode (channel->peer, sizeof (channel->peer), address, sizeof (address)); fprintf (stderr, "%s %s ", channel->ifname, address); if ((format) && (*format)) { va_list arglist; va_start (arglist, format); vfprintf (stderr, format, arglist); va_end (arglist); } fprintf (stderr, "\n"); } return; }
int main(int argc, char *argv[]) { char inbuf[256]; char b64buf[256]; char hexbuf[256]; int len; unsigned char binbuf[256]; fgets(inbuf, sizeof(inbuf), stdin); len = hexdecode(inbuf, binbuf); len = base64encode(binbuf, len, b64buf); b64buf[len] = '\0'; printf("%s\n", b64buf); len = base64decode(b64buf, len, binbuf); hexencode(binbuf, len, hexbuf); hexbuf[2*len] = '\0'; printf("%s\n", hexbuf); return 0; }
void Confirm (struct int6k * int6k, const char *format, ...) { struct channel * channel = (struct channel *)(int6k->channel); struct message * message = (struct message *)(int6k->message); if (_allclr (int6k->flags, INT6K_SILENCE)) { char address [ETHER_ADDR_LEN * 3]; hexdecode (message->ethernet.OSA, sizeof (message->ethernet.OSA), address, sizeof (address)); fprintf (stderr, "%s %s ", channel->name, address); if ((format) && (*format)) { va_list arglist; va_start (arglist, format); vfprintf (stderr, format, arglist); va_end (arglist); } fprintf (stderr, "\n"); } return; }
void urldecode(char *from, char *to) { while(*from != '\0' && *from != ' ' && *from != '\n' && *from != '\r') { switch(*from) { case '+': *to++ = ' '; from++; break; case '%': *to++ = hexdecode(from[1], from[2]); from+=3; break; default: *to++=*from++; break; } } *to='\0'; }
gchar * _g_dbus_auth_run_client (GDBusAuth *auth, GDBusCapabilityFlags offered_capabilities, GDBusCapabilityFlags *out_negotiated_capabilities, GCancellable *cancellable, GError **error) { gchar *s; GDataInputStream *dis; GDataOutputStream *dos; GCredentials *credentials; gchar *ret_guid; gchar *line; gsize line_length; gchar **supported_auth_mechs; GPtrArray *attempted_auth_mechs; GDBusAuthMechanism *mech; ClientState state; GDBusCapabilityFlags negotiated_capabilities; debug_print ("CLIENT: initiating"); ret_guid = NULL; supported_auth_mechs = NULL; attempted_auth_mechs = g_ptr_array_new (); mech = NULL; negotiated_capabilities = 0; credentials = NULL; dis = G_DATA_INPUT_STREAM (g_data_input_stream_new (g_io_stream_get_input_stream (auth->priv->stream))); dos = G_DATA_OUTPUT_STREAM (g_data_output_stream_new (g_io_stream_get_output_stream (auth->priv->stream))); g_filter_input_stream_set_close_base_stream (G_FILTER_INPUT_STREAM (dis), FALSE); g_filter_output_stream_set_close_base_stream (G_FILTER_OUTPUT_STREAM (dos), FALSE); g_data_input_stream_set_newline_type (dis, G_DATA_STREAM_NEWLINE_TYPE_CR_LF); #ifdef G_OS_UNIX if (G_IS_UNIX_CONNECTION (auth->priv->stream) && g_unix_credentials_message_is_supported ()) { credentials = g_credentials_new (); if (!g_unix_connection_send_credentials (G_UNIX_CONNECTION (auth->priv->stream), cancellable, error)) goto out; } else { if (!g_data_output_stream_put_byte (dos, '\0', cancellable, error)) goto out; } #else if (!g_data_output_stream_put_byte (dos, '\0', cancellable, error)) goto out; #endif if (credentials != NULL) { if (G_UNLIKELY (_g_dbus_debug_authentication ())) { s = g_credentials_to_string (credentials); debug_print ("CLIENT: sent credentials `%s'", s); g_free (s); } } else { debug_print ("CLIENT: didn't send any credentials"); } /* TODO: to reduce roundtrips, try to pick an auth mechanism to start with */ /* Get list of supported authentication mechanisms */ s = "AUTH\r\n"; debug_print ("CLIENT: writing `%s'", s); if (!g_data_output_stream_put_string (dos, s, cancellable, error)) goto out; state = CLIENT_STATE_WAITING_FOR_REJECT; while (TRUE) { switch (state) { case CLIENT_STATE_WAITING_FOR_REJECT: debug_print ("CLIENT: WaitingForReject"); line = _my_g_data_input_stream_read_line (dis, &line_length, cancellable, error); if (line == NULL) goto out; debug_print ("CLIENT: WaitingForReject, read '%s'", line); foobar: if (!g_str_has_prefix (line, "REJECTED ")) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "In WaitingForReject: Expected `REJECTED am1 am2 ... amN', got `%s'", line); g_free (line); goto out; } if (supported_auth_mechs == NULL) { supported_auth_mechs = g_strsplit (line + sizeof ("REJECTED ") - 1, " ", 0); #if 0 for (n = 0; supported_auth_mechs != NULL && supported_auth_mechs[n] != NULL; n++) g_printerr ("supported_auth_mechs[%d] = `%s'\n", n, supported_auth_mechs[n]); #endif } g_free (line); mech = client_choose_mech_and_send_initial_response (auth, credentials, (const gchar* const *) supported_auth_mechs, attempted_auth_mechs, dos, cancellable, error); if (mech == NULL) goto out; if (_g_dbus_auth_mechanism_client_get_state (mech) == G_DBUS_AUTH_MECHANISM_STATE_WAITING_FOR_DATA) state = CLIENT_STATE_WAITING_FOR_DATA; else state = CLIENT_STATE_WAITING_FOR_OK; break; case CLIENT_STATE_WAITING_FOR_OK: debug_print ("CLIENT: WaitingForOK"); line = _my_g_data_input_stream_read_line (dis, &line_length, cancellable, error); if (line == NULL) goto out; debug_print ("CLIENT: WaitingForOK, read `%s'", line); if (g_str_has_prefix (line, "OK ")) { if (!g_dbus_is_guid (line + 3)) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Invalid OK response `%s'", line); g_free (line); goto out; } ret_guid = g_strdup (line + 3); g_free (line); if (offered_capabilities & G_DBUS_CAPABILITY_FLAGS_UNIX_FD_PASSING) { s = "NEGOTIATE_UNIX_FD\r\n"; debug_print ("CLIENT: writing `%s'", s); if (!g_data_output_stream_put_string (dos, s, cancellable, error)) goto out; state = CLIENT_STATE_WAITING_FOR_AGREE_UNIX_FD; } else { s = "BEGIN\r\n"; debug_print ("CLIENT: writing `%s'", s); if (!g_data_output_stream_put_string (dos, s, cancellable, error)) goto out; /* and we're done! */ goto out; } } else if (g_str_has_prefix (line, "REJECTED ")) { goto foobar; } else { /* TODO: handle other valid responses */ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "In WaitingForOk: unexpected response `%s'", line); g_free (line); goto out; } break; case CLIENT_STATE_WAITING_FOR_AGREE_UNIX_FD: debug_print ("CLIENT: WaitingForAgreeUnixFD"); line = _my_g_data_input_stream_read_line (dis, &line_length, cancellable, error); if (line == NULL) goto out; debug_print ("CLIENT: WaitingForAgreeUnixFD, read=`%s'", line); if (g_strcmp0 (line, "AGREE_UNIX_FD") == 0) { g_free (line); negotiated_capabilities |= G_DBUS_CAPABILITY_FLAGS_UNIX_FD_PASSING; s = "BEGIN\r\n"; debug_print ("CLIENT: writing `%s'", s); if (!g_data_output_stream_put_string (dos, s, cancellable, error)) goto out; /* and we're done! */ goto out; } else if (g_str_has_prefix (line, "ERROR") && (line[5] == 0 || g_ascii_isspace (line[5]))) { //g_strstrip (line + 5); g_debug ("bah, no unix_fd: `%s'", line + 5); g_free (line); s = "BEGIN\r\n"; debug_print ("CLIENT: writing `%s'", s); if (!g_data_output_stream_put_string (dos, s, cancellable, error)) goto out; /* and we're done! */ goto out; } else { /* TODO: handle other valid responses */ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "In WaitingForAgreeUnixFd: unexpected response `%s'", line); g_free (line); goto out; } break; case CLIENT_STATE_WAITING_FOR_DATA: debug_print ("CLIENT: WaitingForData"); line = _my_g_data_input_stream_read_line (dis, &line_length, cancellable, error); if (line == NULL) goto out; debug_print ("CLIENT: WaitingForData, read=`%s'", line); if (g_str_has_prefix (line, "DATA ")) { gchar *encoded; gchar *decoded_data; gsize decoded_data_len; encoded = g_strdup (line + 5); g_free (line); g_strstrip (encoded); decoded_data = hexdecode (encoded, &decoded_data_len, error); g_free (encoded); if (decoded_data == NULL) { g_prefix_error (error, "DATA response is malformed: "); /* invalid encoding, disconnect! */ goto out; } _g_dbus_auth_mechanism_client_data_receive (mech, decoded_data, decoded_data_len); g_free (decoded_data); if (_g_dbus_auth_mechanism_client_get_state (mech) == G_DBUS_AUTH_MECHANISM_STATE_HAVE_DATA_TO_SEND) { gchar *data; gsize data_len; gchar *encoded_data; data = _g_dbus_auth_mechanism_client_data_send (mech, &data_len); encoded_data = hexencode (data); s = g_strdup_printf ("DATA %s\r\n", encoded_data); g_free (encoded_data); g_free (data); debug_print ("CLIENT: writing `%s'", s); if (!g_data_output_stream_put_string (dos, s, cancellable, error)) { g_free (s); goto out; } g_free (s); } state = CLIENT_STATE_WAITING_FOR_OK; } else { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "In WaitingForData: unexpected response `%s'", line); g_free (line); goto out; } break; default: g_assert_not_reached (); break; } }; /* main authentication client loop */ out: if (mech != NULL) g_object_unref (mech); g_ptr_array_unref (attempted_auth_mechs); g_strfreev (supported_auth_mechs); g_object_unref (dis); g_object_unref (dos); /* ensure return value is NULL if error is set */ if (error != NULL && *error != NULL) { g_free (ret_guid); ret_guid = NULL; } if (ret_guid != NULL) { if (out_negotiated_capabilities != NULL) *out_negotiated_capabilities = negotiated_capabilities; } if (credentials != NULL) g_object_unref (credentials); debug_print ("CLIENT: Done, authenticated=%d", ret_guid != NULL); return ret_guid; }
char * hexstring(char buffer[], size_t length, const byte memory[], size_t extent) { hexdecode (memory, extent, buffer, length); return (buffer); }
signed Antiphon (struct plc * plc, byte source [], byte target []) { struct channel * channel = (struct channel *)(plc->channel); struct message * message = (struct message *)(plc->message); #ifndef __GNUC__ #pragma pack (push,1) #endif struct __packed vs_fr_lbk_request { struct ethernet_hdr ethernet; struct qualcomm_hdr qualcomm; uint8_t DURATION; uint8_t RESERVED; uint16_t LENGTH; uint8_t PACKET [1038]; } * request = (struct vs_fr_lbk_request *) (message); #ifndef __GNUC__ #pragma pack (pop) #endif if (_allclr (plc->flags, PLC_SILENCE)) { char sourcename [ETHER_ADDR_LEN * 3]; char targetname [ETHER_ADDR_LEN * 3]; hexdecode (source, ETHER_ADDR_LEN, sourcename, sizeof (sourcename)); hexdecode (target, ETHER_ADDR_LEN, targetname, sizeof (targetname)); fprintf (stderr, "%s %s %s\n", channel->ifname, sourcename, targetname); } memset (message, 0, sizeof (* message)); EthernetHeader (&request->ethernet, source, target, channel->type); QualcommHeader (&request->qualcomm, 0, 41036); request->DURATION = plc->timer; request->LENGTH = HTOLE16 (sizeof (request->PACKET)); memset (request->PACKET, 0xA5, sizeof (request->PACKET)); EthernetHeader (request->PACKET, target, source, ETHERTYPE_IP); plc->packetsize = sizeof (* request); if (SendMME (plc) <= 0) { error (1, errno, CHANNEL_CANTSEND); } #if 0 /* * This causes a multi-device session to terminate if the device has recently * been removed or powered-off; The device appears to be present but will not * respond; Also, this terminates a session if the network is overloaded with * traffic; */ if (ReadMME (plc, 0, 41037) <= 0) { error (1, errno, CHANNEL_CANTREAD); } #endif sleep (plc->timer); return (0); }
void pcap_enum (flag_t flags) { char report [PCAP_ERRBUF_SIZE]; char string [ETHER_ADDR_LEN * 3]; byte number [ETHER_ADDR_LEN]; pcap_if_t * device; pcap_if_t * devices = (pcap_if_t *)(0); unsigned index; if (pcap_findalldevs (&devices, report) == -1) { error (1, 0, "Can't enumerate interfaces"); } if (!devices) { error (1, 0, "No interfaces available"); } if (_anyset (flags, PCAP_DEVICES)) { for (device = devices, index = 1; device; device = device->next, index++) { gethwaddr (number, device->name); hexdecode (number, sizeof (number), string, sizeof (string)); printf ("%2d %s %s", index, string, device->name); if (device->description) { printf ("\t(%s)", device->description); } printf ("\n"); } } if (_anyset (flags, PCAP_NICS)) { for (device = devices, index = 1; device; device = device->next, index++) { #if defined (WIN32) printf ("ETH%d=%d", index, index); #else printf ("ETH%d=%s", index, device->name); #endif if (device->description) { printf ("\t# %s", device->description); } printf ("\n"); } printf ("\n"); } if (_anyset (flags, PCAP_MACS)) { for (device = devices, index = 1; device; device = device->next, index++) { gethwaddr (number, device->name); hexdecode (number, sizeof (number), string, sizeof (string)); printf ("NIC%d=%s", index, string); if (device->description) { printf ("\t# %s", device->description); } printf ("\n"); } printf ("\n"); } pcap_freealldevs (devices); return; }
gboolean _g_dbus_auth_run_server (GDBusAuth *auth, GDBusAuthObserver *observer, const gchar *guid, gboolean allow_anonymous, GDBusCapabilityFlags offered_capabilities, GDBusCapabilityFlags *out_negotiated_capabilities, GCredentials **out_received_credentials, GCancellable *cancellable, GError **error) { gboolean ret; ServerState state; GDataInputStream *dis; GDataOutputStream *dos; GError *local_error; guchar byte; gchar *line; gsize line_length; GDBusAuthMechanism *mech; gchar *s; GDBusCapabilityFlags negotiated_capabilities; GCredentials *credentials; debug_print ("SERVER: initiating"); ret = FALSE; dis = NULL; dos = NULL; mech = NULL; negotiated_capabilities = 0; credentials = NULL; if (!g_dbus_is_guid (guid)) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "The given guid `%s' is not valid", guid); goto out; } dis = G_DATA_INPUT_STREAM (g_data_input_stream_new (g_io_stream_get_input_stream (auth->priv->stream))); dos = G_DATA_OUTPUT_STREAM (g_data_output_stream_new (g_io_stream_get_output_stream (auth->priv->stream))); g_filter_input_stream_set_close_base_stream (G_FILTER_INPUT_STREAM (dis), FALSE); g_filter_output_stream_set_close_base_stream (G_FILTER_OUTPUT_STREAM (dos), FALSE); g_data_input_stream_set_newline_type (dis, G_DATA_STREAM_NEWLINE_TYPE_CR_LF); /* first read the NUL-byte (TODO: read credentials if using a unix domain socket) */ #ifdef G_OS_UNIX if (G_IS_UNIX_CONNECTION (auth->priv->stream) && g_unix_credentials_message_is_supported ()) { local_error = NULL; credentials = g_unix_connection_receive_credentials (G_UNIX_CONNECTION (auth->priv->stream), cancellable, &local_error); if (credentials == NULL) { g_propagate_error (error, local_error); goto out; } } else { local_error = NULL; byte = g_data_input_stream_read_byte (dis, cancellable, &local_error); if (local_error != NULL) { g_propagate_error (error, local_error); goto out; } } #else local_error = NULL; byte = g_data_input_stream_read_byte (dis, cancellable, &local_error); if (local_error != NULL) { g_propagate_error (error, local_error); goto out; } #endif if (credentials != NULL) { if (G_UNLIKELY (_g_dbus_debug_authentication ())) { s = g_credentials_to_string (credentials); debug_print ("SERVER: received credentials `%s'", s); g_free (s); } } else { debug_print ("SERVER: didn't receive any credentials"); } state = SERVER_STATE_WAITING_FOR_AUTH; while (TRUE) { switch (state) { case SERVER_STATE_WAITING_FOR_AUTH: debug_print ("SERVER: WaitingForAuth"); line = _my_g_data_input_stream_read_line (dis, &line_length, cancellable, error); debug_print ("SERVER: WaitingForAuth, read `%s'", line); if (line == NULL) goto out; if (g_strcmp0 (line, "AUTH") == 0) { s = get_auth_mechanisms (auth, allow_anonymous, "REJECTED ", "\r\n", " "); debug_print ("SERVER: writing `%s'", s); if (!g_data_output_stream_put_string (dos, s, cancellable, error)) { g_free (s); goto out; } g_free (s); g_free (line); } else if (g_str_has_prefix (line, "AUTH ")) { gchar **tokens; const gchar *encoded; const gchar *mech_name; GType auth_mech_to_use_gtype; tokens = g_strsplit (line, " ", 0); g_free (line); switch (g_strv_length (tokens)) { case 2: /* no initial response */ mech_name = tokens[1]; encoded = NULL; break; case 3: /* initial response */ mech_name = tokens[1]; encoded = tokens[2]; break; default: g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Unexpected line `%s' while in WaitingForAuth state", line); g_strfreev (tokens); goto out; } /* TODO: record that the client has attempted to use this mechanism */ //g_debug ("client is trying `%s'", mech_name); auth_mech_to_use_gtype = find_mech_by_name (auth, mech_name); if ((auth_mech_to_use_gtype == (GType) 0) || (!allow_anonymous && g_strcmp0 (mech_name, "ANONYMOUS") == 0)) { /* We don't support this auth mechanism */ g_strfreev (tokens); s = get_auth_mechanisms (auth, allow_anonymous, "REJECTED ", "\r\n", " "); debug_print ("SERVER: writing `%s'", s); if (!g_data_output_stream_put_string (dos, s, cancellable, error)) { g_free (s); goto out; } g_free (s); /* stay in WAITING FOR AUTH */ state = SERVER_STATE_WAITING_FOR_AUTH; } else { gchar *initial_response; gsize initial_response_len; mech = g_object_new (auth_mech_to_use_gtype, "stream", auth->priv->stream, "credentials", credentials, NULL); initial_response = NULL; initial_response_len = 0; if (encoded != NULL) { initial_response = hexdecode (encoded, &initial_response_len, error); if (initial_response == NULL) { g_prefix_error (error, "Initial response is malformed: "); /* invalid encoding, disconnect! */ g_strfreev (tokens); goto out; } } _g_dbus_auth_mechanism_server_initiate (mech, initial_response, initial_response_len); g_free (initial_response); g_strfreev (tokens); change_state: switch (_g_dbus_auth_mechanism_server_get_state (mech)) { case G_DBUS_AUTH_MECHANISM_STATE_ACCEPTED: if (observer != NULL && !g_dbus_auth_observer_authorize_authenticated_peer (observer, auth->priv->stream, credentials)) { /* disconnect */ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, _("Cancelled via GDBusAuthObserver::authorize-authenticated-peer")); goto out; } else { s = g_strdup_printf ("OK %s\r\n", guid); debug_print ("SERVER: writing `%s'", s); if (!g_data_output_stream_put_string (dos, s, cancellable, error)) { g_free (s); goto out; } g_free (s); state = SERVER_STATE_WAITING_FOR_BEGIN; } break; case G_DBUS_AUTH_MECHANISM_STATE_REJECTED: s = get_auth_mechanisms (auth, allow_anonymous, "REJECTED ", "\r\n", " "); debug_print ("SERVER: writing `%s'", s); if (!g_data_output_stream_put_string (dos, s, cancellable, error)) { g_free (s); goto out; } g_free (s); state = SERVER_STATE_WAITING_FOR_AUTH; break; case G_DBUS_AUTH_MECHANISM_STATE_WAITING_FOR_DATA: state = SERVER_STATE_WAITING_FOR_DATA; break; case G_DBUS_AUTH_MECHANISM_STATE_HAVE_DATA_TO_SEND: { gchar *data; gsize data_len; gchar *encoded_data; data = _g_dbus_auth_mechanism_server_data_send (mech, &data_len); encoded_data = hexencode (data); s = g_strdup_printf ("DATA %s\r\n", encoded_data); g_free (encoded_data); g_free (data); debug_print ("SERVER: writing `%s'", s); if (!g_data_output_stream_put_string (dos, s, cancellable, error)) { g_free (s); goto out; } g_free (s); } goto change_state; break; default: /* TODO */ g_assert_not_reached (); break; } } } else { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Unexpected line `%s' while in WaitingForAuth state", line); g_free (line); goto out; } break; case SERVER_STATE_WAITING_FOR_DATA: debug_print ("SERVER: WaitingForData"); line = _my_g_data_input_stream_read_line (dis, &line_length, cancellable, error); debug_print ("SERVER: WaitingForData, read `%s'", line); if (line == NULL) goto out; if (g_str_has_prefix (line, "DATA ")) { gchar *encoded; gchar *decoded_data; gsize decoded_data_len; encoded = g_strdup (line + 5); g_free (line); g_strstrip (encoded); decoded_data = hexdecode (encoded, &decoded_data_len, error); g_free (encoded); if (decoded_data == NULL) { g_prefix_error (error, "DATA response is malformed: "); /* invalid encoding, disconnect! */ goto out; } _g_dbus_auth_mechanism_server_data_receive (mech, decoded_data, decoded_data_len); g_free (decoded_data); /* oh man, this goto-crap is so ugly.. really need to rewrite the state machine */ goto change_state; } else { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Unexpected line `%s' while in WaitingForData state", line); g_free (line); } goto out; case SERVER_STATE_WAITING_FOR_BEGIN: debug_print ("SERVER: WaitingForBegin"); /* Use extremely slow (but reliable) line reader - this basically * does a recvfrom() system call per character * * (the problem with using GDataInputStream's read_line is that because of * buffering it might start reading into the first D-Bus message that * appears after "BEGIN\r\n"....) */ line = _my_g_input_stream_read_line_safe (g_io_stream_get_input_stream (auth->priv->stream), &line_length, cancellable, error); debug_print ("SERVER: WaitingForBegin, read `%s'", line); if (line == NULL) goto out; if (g_strcmp0 (line, "BEGIN") == 0) { /* YAY, done! */ ret = TRUE; g_free (line); goto out; } else if (g_strcmp0 (line, "NEGOTIATE_UNIX_FD") == 0) { g_free (line); if (offered_capabilities & G_DBUS_CAPABILITY_FLAGS_UNIX_FD_PASSING) { negotiated_capabilities |= G_DBUS_CAPABILITY_FLAGS_UNIX_FD_PASSING; s = "AGREE_UNIX_FD\r\n"; debug_print ("SERVER: writing `%s'", s); if (!g_data_output_stream_put_string (dos, s, cancellable, error)) goto out; } else { s = "ERROR \"fd passing not offered\"\r\n"; debug_print ("SERVER: writing `%s'", s); if (!g_data_output_stream_put_string (dos, s, cancellable, error)) goto out; } } else { g_debug ("Unexpected line `%s' while in WaitingForBegin state", line); g_free (line); s = "ERROR \"Unknown Command\"\r\n"; debug_print ("SERVER: writing `%s'", s); if (!g_data_output_stream_put_string (dos, s, cancellable, error)) goto out; } break; default: g_assert_not_reached (); break; } } g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Not implemented (server)"); out: if (mech != NULL) g_object_unref (mech); if (dis != NULL) g_object_unref (dis); if (dos != NULL) g_object_unref (dos); /* ensure return value is FALSE if error is set */ if (error != NULL && *error != NULL) { ret = FALSE; } if (ret) { if (out_negotiated_capabilities != NULL) *out_negotiated_capabilities = negotiated_capabilities; if (out_received_credentials != NULL) *out_received_credentials = credentials != NULL ? g_object_ref (credentials) : NULL; } if (credentials != NULL) g_object_unref (credentials); debug_print ("SERVER: Done, authenticated=%d", ret); return ret; }