4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #include <glib/gprintf.h>
25 #include "sipe-digest.h"
28 static const char *epid_ns_uuid
= "fcacfb03-8a73-46ef-91b1-e5ebeeaba4fe";
31 * This assumes that the structure is correctly packed on all target
32 * platforms, i.e. sizeof(uuid_t) == 16
34 * See also the test added to "configure". On Windows platform we know
35 * that #pragma pack() exists and therefore can use it in the code.
44 guint16 time_hi_and_version
;
45 guint8 clock_seq_hi_and_reserved
;
53 #define UUID_OFFSET_TO_LAST_SEGMENT 24
55 static void readUUID(const char *string
, uuid_t
*uuid
)
58 /* Some platforms don't allow scanning to char using %02hhx */
61 sscanf(string
, "%08x-%04hx-%04hx-%02hx%02hx-", &uuid
->time_low
62 , &uuid
->time_mid
, &uuid
->time_hi_and_version
64 uuid
->clock_seq_hi_and_reserved
= tmp1
;
65 uuid
->clock_seq_low
= tmp2
;
69 sscanf(&string
[UUID_OFFSET_TO_LAST_SEGMENT
+i
*2], "%02hx", &tmp1
);
74 static void printUUID(uuid_t
*uuid
, char *string
)
78 sprintf(string
, "%08x-%04x-%04x-%02x%02x-", uuid
->time_low
79 , uuid
->time_mid
, uuid
->time_hi_and_version
80 , uuid
->clock_seq_hi_and_reserved
86 pos
+= sprintf(&string
[pos
], "%02x", uuid
->node
[i
]);
90 static void createUUIDfromHash(uuid_t
*uuid
, const unsigned char *hash
)
92 memcpy(uuid
, hash
, sizeof(uuid_t
));
93 uuid
->time_hi_and_version
&= GUINT16_TO_LE(0x0FFF);
94 uuid
->time_hi_and_version
|= GUINT16_TO_LE(0x5000);
95 uuid
->clock_seq_hi_and_reserved
&= 0x3F;
96 uuid
->clock_seq_hi_and_reserved
|= 0x80;
99 char *generateUUIDfromEPID(const gchar
*epid
)
103 guchar digest
[SIPE_DIGEST_SHA1_LENGTH
];
105 readUUID(epid_ns_uuid
, &result
);
107 result
.time_low
= GUINT32_FROM_LE(result
.time_low
);
108 result
.time_mid
= GUINT16_FROM_LE(result
.time_mid
);
109 result
.time_hi_and_version
= GUINT16_FROM_LE(result
.time_hi_and_version
);
111 memcpy(buf
, &result
, sizeof(uuid_t
));
112 strcpy(&buf
[sizeof(uuid_t
)], epid
);
114 sipe_digest_sha1((guchar
*)buf
, strlen(buf
), digest
);
115 createUUIDfromHash(&result
, digest
);
117 result
.time_low
= GUINT32_TO_LE(result
.time_low
);
118 result
.time_mid
= GUINT16_TO_LE(result
.time_mid
);
119 result
.time_hi_and_version
= GUINT16_TO_LE(result
.time_hi_and_version
);
121 printUUID(&result
, buf
);
122 return g_strdup(buf
);
126 * Generates epid from user SIP URI, hostname and IP address.
127 * Thus epid will be the same each start and
128 * not needed to be persistent.
130 * Using MAC address proved to be poorly portable solution.
134 char *sipe_get_epid(const char *self_sip_uri
,
135 const char *hostname
,
136 const char *ip_address
)
138 /* 6 last digits of hash */
139 #define SIPE_EPID_HASH_START 14
140 #define SIPE_EPID_HASH_END SIPE_DIGEST_SHA1_LENGTH
141 #define SIPE_EPID_LENGTH (2 * (SIPE_EPID_HASH_END - SIPE_EPID_HASH_START + 1))
144 char out
[SIPE_EPID_LENGTH
+ 1];
145 char *buf
= g_strdup_printf("%s:%s:%s", self_sip_uri
, hostname
, ip_address
);
146 guchar hash
[SIPE_DIGEST_SHA1_LENGTH
];
148 sipe_digest_sha1((guchar
*) buf
, strlen(buf
), hash
);
149 for (i
= SIPE_EPID_HASH_START
, j
= 0;
150 i
< SIPE_EPID_HASH_END
;
152 g_sprintf(&out
[j
], "%02x", hash
[i
]);
154 out
[SIPE_EPID_LENGTH
] = 0;
157 return g_strdup(out
);